标签:
Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流!
网络模型:
OSI参考模型
TCP/IP参考模型
网络参考模型图
网络通讯的要素:
IP地址:InetAddress
网络中设备的标识
不容易记忆,可以用主机名
本地回环地址:127.0.0.1;主机名:localhost
端口号
用于标识进程的逻辑地址,不同进程的标识
有效端口:0~65535,其中0~1024为系统使用端口或保留端口
网络协议
是一种网络通讯的规则
常见协议:TCP,UDP
UDP:
1、将数据及源和目的封装到数据包中,不需要建立连接
2、每个数据包的大小限制在64K之内
3、因无连接,所以是不可靠的协议
4、不需要建立连接,所以速度较快
TCP:
1、建立连接,形成传输数据的通道
2、在连接中进行大数据量的传输
3、通过三次握手建立连接,是可靠的协议
4、因为必须要建立连接,所以传输效率稍低
Socket:
1、Socket就是为网络服务提供的一种机制。俗称套接字,相当于一个插头。
2、进行通信的两端都有Socket
3、网络通信其实就是Socket之间的通信
4、数据在两个Socket之间通过IO传输
5、在网络传输中,发送端/客户端和接收端/服务端通常是两个独立运行的程序。
UDP传输:
1、需要的两个对象:DatagramSocket和DatagramPacket
2、建立发送端,接收端
3、建立数据包
4、调用Socket的发送、接受方法
5、关闭Socket。
发送端:
在发送端,要在数据包中对象中明确目的地IP和端口号
接收端:
接收端要明确指定监听的端口
代码示例:
import java.net.*; /* 需求:通过udp传输方式,将一段文字数据发送出去。定义一个udp发送端。 思路: 1,建立updsocket服务。 2,提供数据,并将数据封装到数据包中。 3,通过socket服务的发送功能,将数据包发出去。 4,关闭资源。 */ class UdpSend{ public static void main(String[] args) throws Exception{ //1,创建udp服务。通过DatagramSocket对象。 DatagramSocket ds = new DatagramSocket(8888); //2,确定数据,并封装成数据包。DatagramPacket(byte[] buf, int length, InetAddress address, int port) byte[] buf = "udp ge men lai le ".getBytes(); DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.254"),10000); //3,通过socket服务,将已有的数据包发送出去。通过send方法。 ds.send(dp); //4,关闭资源。 ds.close(); } } /* 需求: 定义一个应用程序,用于接收udp协议传输的数据并处理。 定义udp的接收端。 思路: 1,定义udpsocket服务。通常会监听一个端口。其实就是给这个接收网络应用程序定义数字标识。方便于明确哪些数据过来该应用程序可以处理。 2,定义一个数据包,因为要存储接收到的字节数据。因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。 3,通过socket服务的receive方法将收到的数据存入已定义好的数据包中。 4,通过数据包对象的特有功能。将这些不同的数据取出。打印在控制台上。 5,关闭资源。 */ class UdpRece{ public static void main(String[] args) throws Exception{ //1,创建udp socket,建立端点。 DatagramSocket ds = new DatagramSocket(10000); while(true){ //2,定义数据包。用于存储数据。 byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf,buf.length); //3,通过服务的receive方法将收到数据存入数据包中。 ds.receive(dp);//阻塞式方法。 //4,通过数据包的方法获取其中的数据。 String ip = dp.getAddress().getHostAddress(); String data = new String(dp.getData(),0,dp.getLength()); int port = dp.getPort(); System.out.println(ip+"::"+data+"::"+port); } //5,关闭资源,(可选) //ds.close(); } }
TCP传输:
1、需要的对象:Socket和ServerSocket
2、建立客户端和服务器端
3、建立连接后,通过Socket中的IO流进行数据传输
4、关闭socket
客户端基本思路:
*客户端需要明确服务器的IP地址以及端口,这样才可以试着去建立连接,如果连接失败,会出现异常。
*连接成功,说明客户端和服务端建立了通道,那么通过IO流就可以进行数据的传输。
*Socket已经提供了输出流和输入流的对象,可以通过getInputStream()和getOutputStream()方法获得。
*与服务端完成数据传输后,关闭Socket即可。
服务端基本思路:
*服务端需要明确它要处理的数据是从哪一个端口进入的。
*当有客户端访问时,它需要明确是哪一个客户端。可通过accept()方法获取要访问的客户端对象,并通过该对象与客户端通过IO流进行数据传输
*当该客户端访问结束后,关闭该客户端。
代码示例:
/* 演示tcp传输。 1,tcp分客户端和服务端。 2,客户端对应的对象是Socket。 服务端对应的对象是ServerSocket。 */ /* 客户端, 通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机。 因为tcp是面向连接的。所以在建立socket服务时, 就要有服务端存在,并连接成功。形成通路后,在该通道进行数据的传输。 需求:给服务端发送给一个文本数据。 步骤: 1,创建Socket服务。并指定要连接的主机和端口。 */ import java.io.*; import java.net.*; class TcpClient{ public static void main(String[] args) throws Exception { //创建客户端的socket服务。指定目的主机和端口 Socket s = new Socket("192.168.1.254",10003); //为了发送数据,应该获取socket流中的输出流。 OutputStream out = s.getOutputStream(); out.write("tcp ge men lai le ".getBytes()); s.close(); } } /* 需求:定义端点接收数据并打印在控制台上。 服务端: 1,建立服务端的socket服务。ServerSocket();并监听一个端口。 2,获取连接过来的客户端对象。通过ServerSokcet的 accept方法。没有连接就会等,所以这个方法阻塞式的。 3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。并打印在控制台。 4,关闭服务端。(可选) */ class TcpServer{ public static void main(String[] args) throws Exception{ //建立服务端socket服务。并监听一个端口。 ServerSocket ss = new ServerSocket(10003); //通过accept方法获取连接过来的客户端对象。 while(true){ Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+".....connected"); //获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据。 InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); System.out.println(new String(buf,0,len)); s.close();//关闭客户端. } //ss.close(); } }
TCP传输最容易出现的问题:
1、客户端和服务端连接上之后,两端都在等待,没有任何数据传输。
原因是read()方法和readLine()方法都是阻塞式方法。
2、解决办法:
1、自定义结束标记
2、使用shutdownInput和shutdownOutput方法。
练习:
需求:建立一个文本转换服务器。客户端给服务端发送文本,服务单会将文本转成大写在返回给客户端。而且客户度可以不断的进行文本转换。当客户端输入over时,转换结束。
/*
分析: 客户端: 既然是操作设备上的数据,那么就可以使用io技术,并按照io的操作规律来思考。 源:键盘录入。 目的:网络设备,网络输出流。 而且操作的是文本数据。可以选择字符流。 步骤 1,建立服务。 2,获取键盘录入。 3,将数据发给服务端。 4,后去服务端返回的大写数据。 5,结束,关资源。 */ import java.io.*; import java.net.*; class TransClient{ public static void main(String[] args) throws Exception{ Socket s = new Socket("192.168.1.254",10005); //定义读取键盘数据的流对象。 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); //定义目的,将数据写入到socket输出流。发给服务端。 //BufferedWriter bufOut = //new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); PrintWriter out = new PrintWriter(s.getOutputStream(),true); //定义一个socket读取流,读取服务端返回的大写信息。 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = null; while((line=bufr.readLine())!=null){ if("over".equals(line)) break; out.println(line); // bufOut.write(line); // bufOut.newLine();//此处如果没有换行标记,就会使两端都等待 // bufOut.flush(); String str =bufIn.readLine(); System.out.println("server:"+str); } bufr.close(); s.close(); } } /* 服务端: 源:socket读取流。 目的:socket输出流。 都是文本,装饰。 */ class TransServer{ public static void main(String[] args) throws Exception{ ServerSocket ss = new ServerSocket(10005); Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+"....connected"); //读取socket读取流中的数据。 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); //目的。socket输出流。将大写数据写入到socket输出流,并发送给客户端。 //BufferedWriter bufOut = //new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); PrintWriter out = new PrintWriter(s.getOutputStream(),true); String line = null; while((line=bufIn.readLine())!=null){ System.out.println(line); out.println(line.toUpperCase()); // bufOut.write(line.toUpperCase()); // bufOut.newLine(); // bufOut.flush(); } s.close(); ss.close(); } }
标签:
原文地址:http://www.cnblogs.com/alvis2015/p/4298064.html