TCP,UDP通信使用场景及区别比较
在文章《基于java的TCP通信》我们实现了基于TCP传输协议的通信,但是在物联网设备数据传输过程中《Arduino+ESP8266上传数据到服务器》,《Arduino+ESP8266接收服务器信息》,《Arduino+ESP8266接收服务器信息——源代码分析》,测试程序发现终端和服务器在接收数据的时候总会出现一些问题,如:结束数据不及时,TCP建立时间长,传输数据不成功等问题。于是,我们考虑通过UDP协议来实现该功能。TCP和UDP传输协议的区别列举如下:
TCP通信协议
-
TCP是面向连接的;
-
每条TCP连接只能由于两个端点,一对一通信;
-
TCP提供可靠的交付服务,传输数据无差错,不丢失,不重复,且按时序到达;
-
TCP提供全双工通信;
-
面向字节流,TCP根据对方给出的窗口和当前的网络拥塞程度决定一个报文应该包含多少个字节。
UDP通信协议
-
无连接;
-
UDP使用尽最大努力交付,不保证可靠性UDP是面向报文的,UDP对应用层交付下来的报文,既不合并,也不拆分,而是保留报文的边界;
-
应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文;
-
UDP没有拥塞控制;
-
UDP支持一对一,一对多,多对一和多对多的交互通信。
-
UDP的首部开销小,只有8字节。
应用场景上的区别:
TCP协议需要三次握手通信成功后进行建立,应用场景:互联网和企业网上客户端应用,数据传输性能让位于数据传输的完整性,可控制性和可靠性。
UDP协议是直接发送,不会判断是否接收和发送成功,应用场景:当强调输出性能而非完整性时,如音频和多媒体的应用。
TCP/UDP 服务端,客户端交互步骤:
与TCP程序设计相比较,UDP缺少了connect()、listen()及accept()函数,这是用于UDP协议无连接的特性,不用维护TCP的连接、断开等状态。
服务器源代码
package udpserver.damuchacha;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class UDPServer {
public static void main(String[] args) throws IOException {
//接收客户端发送的数据
DatagramSocket socket = new DatagramSocket(8800);
// 1.创建服务器端DatagramSocket,指定端口
// 2.创建数据报,用于接收客户端发送的数据
byte[] data = new byte[1024];//创建字节数组,指定接收的数据包的大小
DatagramPacket packet = new DatagramPacket(data, data.length);
// 3.接收客户端发送的数据
System.err.println("Server:");//输出服务器的标识
while(true) {//通过循环不停的向客户端发送数据和接收数据
socket.receive(packet);// 此方法在接收到数据报之前会一直阻塞
// 4.读取数据
String info = new String(data, 0, packet.getLength());//创建字符串对象
System.out.println("服务器接收到客户端的信息是:" + info);
//输出提示信息
//向客户端响应数据
// 1.定义客户端的地址、端口号、数据
System.out.println("回复客户端的消息:");
InetAddress address = packet.getAddress();
//获取发送端的地址
int port = packet.getPort();
//获取 发送端进程所绑定的端口
Scanner scanner = new Scanner(System.in);
//从键盘接受数据
String send = scanner.nextLine();
//nextLine方式接受字符串
byte[] data2 = send.getBytes();
//将接收到的数据转换为字节数组
DatagramPacket packet2 = new DatagramPacket(data2, data2.length,address,port);
// 2.创建数据报,包含响应的数据信息
socket.send(packet2);
// 3.响应客户端
}
}
}
客户端源代码
package udpclient.damuchacha;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class UDPClient {
public static void main(String[] args) throws IOException {
//向服务器端发送数据
InetAddress address = InetAddress.getByName("localhost");
// 1.定义服务器的地址、端口号、数据
int port = 8800;
System.err.println("Client:");//输出客户端的标识
while(true) {//通过循环不同的向客户端发送和接受数据
System.out.println("请输入发送给客户端的消息:");
Scanner scanner = new Scanner(System.in);
//从键盘接受数据
String send = scanner.nextLine();
//nextLine方式接受字符串
byte[] data = send.getBytes();
//将接收到的数据变成字节数组
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);//2.创建数据报,包含发送的数据信息
DatagramSocket socket = new DatagramSocket();
// 3.创建DatagramSocket对象
socket.send(packet);
// 4.向服务器端发送数据报
//接收服务器端响应的数据
byte[] data2 = new byte[1024];
DatagramPacket packet2 = new DatagramPacket(data2, data2.length);
// 1.创建数据报,用于接收服务器端响应的数据
socket.receive(packet2);
// 2.接收服务器响应的数据
//3.读取数据
String reply = new String(data2, 0, packet2.getLength());
//创建字符串对象
System.out.println("客户端接收到服务器的信息是:" + reply);
//输出提示信息
socket.close();
//4.关闭资源
}
}
}
客户端输出结果:
服务器输出结果
完
2018/8/22 夜