javaTCP和UDP传输协议

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javaTCP和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类

在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     @Override
10     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 }
ServerThread

在输入流和输出流中采用循环可客户端传输信息

技术分享
 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 }
TestClientString

在客户端中采用循环,可以让客户端与服务器建立一次连接,实现多次通信

基于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,port
10         InetAddress ia=InetAddress.getLocalHost();
11         System.out.println(ia.toString());
12         String str="吴兴国";
13         byte[] data=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 receive
18         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 resorce
23         ds.close();
24         }catch(IOException e){
25             e.printStackTrace();
26         }
27     }
28 
29 }
UDPSender

接收方:

技术分享
 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 data
11          */
12         byte []data=new byte[1024];
13         DatagramPacket dp=new DatagramPacket(data,data.length);
14         /*
15          * receive source
16          */
17         ds.receive(dp);
18         System.out.println("contents are:"+new String(data,0,dp.getLength()));
19         /*
20          * send data
21          */
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 resource
31          */
32         }catch(SocketException e){
33             e.printStackTrace();
34         }catch(IOException e){
35             e.printStackTrace();
36         }
37     }
38 
39 }
UDPReceiver

网络编程中定义端口应注意

互联网中的协议被分为三种,

  • 众所周知(Well Known Ports)端口:编号0~1023,通常由操作系统分配,用于标识一些众所周知的服务。众所周知的端口编号通常又IANA统一分配
  • 注册(Registered Ports)端口:编号1024~49151,可以动态的分配给不同的网络应用进程。
  • 私有(Private Ports)端口:编号49159~65535,一般情况下,这些端口不分配网络应用进程。

参考文章:

因特网中端口

以上是关于javaTCP和UDP传输协议的主要内容,如果未能解决你的问题,请参考以下文章

传输层协议之UDP

java 25 - 4 网络编程之 UDP协议传输的代码优化

网络基础:TCP协议UDP协议均属于传输层协议;TCP和UDP协议有何不同?

技术讲座 I 传输层UDP协议

传输层协议 ——— UDP协议

UDP、TCP 协议区别?