UDP和TCP:
UDP(User Datagram Protocol):用户数据报协议
UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据报的方法
UDP的特点:
UDP是一个无连接协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。
在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。
由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。
UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包而言UDP的额外开销很小。
吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。
UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。
虽然UDP是一个不可靠的协议,但它是分发信息的一个理想协议。例如,在屏幕上报告股票市场、显示航空信息等等。UDP也用在路由信息协议RIP(Routing Information Protocol)中修改路由表。在这些应用场合下,如果有一个消息丢失,在几秒之后另一个新的消息就会替换它。UDP广泛用在多媒体应用中。
UDP的一个简单实现:
服务端:
package com.wish; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class UdpSocketServer { public static void main(String[] args) throws IOException { System.out.println("udp服务器端启动连接...."); DatagramSocket ds = new DatagramSocket(8090); byte[] bytes = new byte[1024]; DatagramPacket dp = new DatagramPacket(bytes, bytes.length); // 阻塞,等待接受客户端发送请求 ds.receive(dp); System.out.println("来源:"+dp.getAddress()+",端口号:"+dp.getPort()); // 获取客户端请求内容 String str=new String(dp.getData(),0,dp.getLength()); System.out.println("str:"+str); ds.close(); } }
客户端:
package com.wish; import org.junit.jupiter.api.Test; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class UdpClient { public static void main(String[] args) throws IOException { System.out.println("udp客户端启动连接...."); DatagramSocket ds = new DatagramSocket(); String str="123456789"; byte[] bytes= str.getBytes(); DatagramPacket dp= new DatagramPacket(bytes, bytes.length, InetAddress.getByName("127.0.0.1"),8080); ds.send(dp); ds.close(); } }
TCP(Transmission Control Protocol):传输控制协议
TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议
TCP的特点:
TCP是一种面向广域网的通信协议,目的是在跨越多个网络通信时,为两个通信端点之间提供一条具有下列特点的通信方式:
(1)基于流的方式;
(2)面向连接;
(3)可靠通信方式;
(4)在网络状况不佳的时候尽量降低系统由于重传带来的带宽开销;
(5)通信连接维护是面向通信的两个端点的,而不考虑中间网段和节点。
为满足TCP协议的这些特点,TCP协议做了如下的规定:
①数据分片:在发送端对用户数据进行分片,在接收端进行重组,由TCP确定分片的大小并控制分片和重组;
②到达确认:接收端接收到分片数据时,根据分片数据序号向发送端发送一个确认;
③超时重发:发送方在发送分片时启动超时定时器,如果在定时器超时之后没有收到相应的确认,重发分片;
④滑动窗口:TCP连接每一方的接收缓冲空间大小都固定,接收端只允许另一端发送接收端缓冲区所能接纳的数据,TCP在滑动窗口的基础上提供流量控制,防止较快主机致使较慢主机的缓冲区溢出;
⑤失序处理:作为IP数据报来传输的TCP分片到达时可能会失序,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层;
⑥重复处理:作为IP数据报来传输的TCP分片会发生重复,TCP的接收端必须丢弃重复的数据;
⑦数据校验:TCP将保持它首部和数据的检验和,这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到分片的检验和有差错,TCP将丢弃这个分片,并不确认收到此报文段导致对端超时并重发。
TCP的一个简单实现
服务端
package com.wish; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; public class TcpServer { public static void main(String[] args) throws IOException { System.out.println("socket tcp服务器端启动...."); ServerSocket serverSocket = new ServerSocket(8080); // 等待客户端请求 Socket accept = serverSocket.accept(); InputStream inputStream = accept.getInputStream(); // 转换成string类型 byte[] buf = new byte[1024]; int len = inputStream.read(buf); String str = new String(buf, 0, len); System.out.println("服务器接受客户端内容:" + str); } }
客户端
package com.wish; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; public class TcpClient { public static void main(String[] args) throws IOException { System.out.println("socket tcp 客户端启动...."); Socket socket = new Socket("192.168.60.29", 8080); OutputStream outputStream = socket.getOutputStream(); outputStream.write("黑夜就是你的面纱".getBytes()); socket.close(); } }
协议对比:
UDP和TCP协议的主要区别是两者在如何实现信息的可靠传递方面不同。
TCP协议中包含了专门的传递保证机制,当数据接收方收到发送方传来的信息时,会自动向发送方发出确认消息;发送方只有在接收到该确认消息之后才继续传送其它信息,否则将一直等待直到收到确认信息为止。
与TCP不同,UDP协议并不提供数据传送的保证机制。
如果在从发送方到接收方的传递过程中出现数据包的丢失,协议本身并不能做出任何检测或提示。
因此,通常人们把UDP协议称为不可靠的传输协议。
TCP 是面向连接的传输控制协议,而UDP 提供了无连接的数据报服务;TCP 具有高可靠性,确保传输数据的正确性,不出现丢失或乱序;UDP 在传输数据前不建立连接,不对数据报进行检查与修改,无须等待对方的应答,所以会出现分组丢失、重复、乱序,应用程序需要负责传输可靠性方面的所有工作;UDP 具有较好的实时性,工作效率较 TCP 协议高;UDP 段结构比 TCP 的段结构简单,因此网络开销也小。
TCP 协议可以保证接收端毫无差错地接收到发送端发出的字节流,为应用程序提供可靠的通信服务。
对可靠性要求高的通信系统往往使用 TCP 传输数据。