首页 > 代码库 > 【java】TCP和UDP传输协议
【java】TCP和UDP传输协议
TCP协议和UDP协议的比较
TCP的全称是Transmission Control Protocol (传输控制协议)
- 传输控制协议,是一种面向连接的协议,类似打电话
- 在通信的整个过程中保持连接
- 保证了数据传递的可靠性和有序性
- 是一种全双工的字节流通信方式
- 服务器压力比较大,资源消耗比较快,发送数据效率比较低
UDP是User Datagram Protocol(用户数据报协议)
- 用户数据报协议,是一种非面向连接的协议,类似写信
- 在通信的整个过程中不需要保持连接
- 不保证数据传输的可靠性和有序性
- 是一种双全工的数据报通信方式
- 服务器压力比较小,资源比较低,发送效率比较高
基于TCP的网络编程模型
服务器:
- 创建ServerSocket的对象并且提供端口号, public ServerSocket(int port)
- 等待客户端的请求连接,使用accept()方法, public Socket accept()
- 连接成功后,使用Socket得到输入流和输入流,进行通信
- 关闭相关资源
客户端:
- 创建Socket类型的对象,并且提供IP地址和端口号, public Socket(String host, int port)
- 使用Socket构造输入流和输出流进行通信
- 关闭相关资源
下面这个例子
1 /* 2 * 在提供端口号的时候应该注意:最好定义在1024~49151。 3 */ 4 public class TestServerString { 5 6 public static void main(String[] args) { 7 try{ 8 //1.创建ServerSocket类型的对象,并提供端口号 9 ServerSocket ss = new ServerSocket(8888);10 //2.等待客户端的连接请求,使用accept()方法,保持阻塞状态11 while(true){12 System.out.println("等待客户端的连接请求...");13 Socket s = ss.accept();14 new ServerThread(s).start();15 System.out.println("客户端连接成功!");16 }17 18 }catch(Exception e){19 e.printStackTrace();20 }21 22 }23 24 }
在TestServerString类中采用循环相应多个客户端的连接,
1 public class ServerThread extends Thread{ 2 3 private Socket s; 4 5 public ServerThread(Socket s){ 6 this.s=s; 7 } 8 9 @Override10 public void run(){11 try{12 BufferedReader br = new BufferedReader(13 new InputStreamReader(s.getInputStream()));14 PrintStream ps = new PrintStream(s.getOutputStream());15 //编程实现服务器可以不断地客户端进行通信16 while(true){17 //服务器接收客户端发来的消息并打印18 String str = br.readLine();19 //当客户端发来"bye"时,结束循环20 if("bye".equalsIgnoreCase(str)) break;21 System.out.println(s.getLocalAddress()+":"+ str); 22 //向客户端回发消息“I received!”23 ps.println("server received!");24 }25 //4.关闭相关的套接字26 ps.close();27 br.close();28 s.close();29 }catch(Exception e){30 e.printStackTrace();31 }32 }33 }
在输入流和输出流中采用循环可客户端传输信息
1 public class TestClientString { 2 3 public static void main(String[] args) { 4 5 try{ 6 //1.创建Socket类型的对象,并指定IP地址和端口号 7 Socket s = new Socket("127.0.0.1", 8888); 8 //2.使用输入输出流进行通信 9 BufferedReader br = new BufferedReader(10 new InputStreamReader(System.in));11 PrintStream ps = new PrintStream(s.getOutputStream());12 BufferedReader br2 = new BufferedReader(13 new InputStreamReader(s.getInputStream()));14 //编程实现客户端不断地和服务器进行通信15 while(true){16 //提示用户输入要发送的内容17 System.out.println("请输入要发送的内容:");18 String msg = br.readLine();19 ps.println(msg);20 //当客户端发送"bye"时,结束循环21 if("bye".equalsIgnoreCase(msg)){ 22 break;23 };24 //等待接收服务器的回复,并打印回复的结果25 String str2 = br2.readLine();26 System.out.println("服务器发来的消息是:" + str2);27 }28 //3.关闭Socket对象29 br2.close();30 br.close();31 ps.close();32 s.close();33 }catch(Exception e){34 e.printStackTrace();35 }36 37 }38 39 }
在客户端中采用循环,可以让客户端与服务器建立一次连接,实现多次通信
基于UDP的网络编程模型
发送方:
- 创建DatagramSocket类型的对象,不需要提供任何信息, public DatagramSocket()
- 创建DatagramPacket类型的对象,指定发送的内容、IP地址、端口号, public DatagramPacket(byte[] buf, int length, InetAddress address, int port)
- 发送数据,使用send()方法, public void send(DatagramPacket p)
- 关闭相关的资源
接收方:
- 创建DatagramSocket类型的对象,并且指定端口, public DatagramSocket(int port)
- 创建DatagramPacket类型的对象,用于接收发来的数据, public DatagramPacket(byte[] buf, int length)
- 接收数据,使用receive()方法, public void receive(DatagramPacket p)
- 关闭相关资源
例:
发送方:
1 public class UDPSender { 2 3 public static void main(String[] args) { 4 try{ 5 /* 6 * create DatagramSocket instance 7 */ 8 DatagramSocket ds=new DatagramSocket(); 9 //create DatagramPackage instance and specify the content to send ,ip address,port10 InetAddress ia=InetAddress.getLocalHost();11 System.out.println(ia.toString());12 String str="吴兴国";13 byte[] data=http://www.mamicode.com/str.getBytes();14 DatagramPacket dp=new DatagramPacket(data,data.length,ia,8888);15 //send data use send()16 ds.send(dp);17 //create DatagramPacket instance for receive18 byte []b2=new byte[1024];19 DatagramPacket dp2=new DatagramPacket(b2,b2.length);20 ds.receive(dp2);21 System.out.println("result:"+new String(data));22 //close resorce23 ds.close();24 }catch(IOException e){25 e.printStackTrace();26 }27 }28 29 }
接收方:
1 public class UDPReceiver { 2 3 public static void main(String[] args) { 4 try{ 5 /* 6 * create DatagramSocket instance,and support port 7 */ 8 DatagramSocket ds=new DatagramSocket(8888); 9 /*10 * create DatagramPackage instance for receive data11 */12 byte []data=http://www.mamicode.com/new byte[1024];13 DatagramPacket dp=new DatagramPacket(data,data.length);14 /*15 * receive source16 */17 ds.receive(dp);18 System.out.println("contents are:"+new String(data,0,dp.getLength()));19 /*20 * send data21 */22 String str="I received!";23 byte[] b2=str.getBytes();24 DatagramPacket dp2=25 new DatagramPacket(b2,b2.length,dp.getAddress(),dp.getPort());26 ds.send(dp2);27 System.out.println("发送成功,ip:"+dp.getAddress());28 29 /*30 * close resource31 */32 }catch(SocketException e){33 e.printStackTrace();34 }catch(IOException e){35 e.printStackTrace();36 }37 }38 39 }
网络编程中定义端口应注意
互联网中的协议被分为三种,
- 众所周知(Well Known Ports)端口:编号0~1023,通常由操作系统分配,用于标识一些众所周知的服务。众所周知的端口编号通常又IANA统一分配
- 注册(Registered Ports)端口:编号1024~49151,可以动态的分配给不同的网络应用进程。
- 私有(Private Ports)端口:编号49159~65535,一般情况下,这些端口不分配网络应用进程。
参考文章:
因特网中端口
【java】TCP和UDP传输协议
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。