UDP 小结
参考《图解TCP_IP》
UDP 协议端格式
-
源端口号(Source Port)
表示发送端端口号,字段长 16 位。该字段是可选项,有时可能不会设置源端口号。没有源端口号的时候该字段设置为 0 。可用于不需要返回的通信中。
-
目标端口号(Destination Port)
表示接收端端口号,字段长度 16 位。
-
UDP 长度(Length)
该字段保存了 UDP 首部的长度跟数据的长度之和。单位为字节。
-
校验和(Checksum)
UDP 中使用的是 CRC 校验;
发送端会根据数据内容计算一个校验和,数据到达接收端后,也会重新计算一个校验和,如果不相同就说明数据已经出错,接收端会丢弃该数据报。
除了CRC这种简单的校验,还有md5字符串哈希算法。
1.不管源字符串有多长,得到的hash结果都是固定长度的(64位/128位)。
2.原串如果相同,得到的hash值一定相同,原串如果不同(哪怕差别很小)得到的hash值也会差别特别大。
3.根据原串得到md5很简单,根据md5推算回原串
几乎不可能。在 Linux 中使用
md5sum
命令来计算。
UDP的特点
- 无连接:知道对端的 IP 和端口号就直接进行传输,不需要建立连接。
- 不可靠:没有确认机制,没有重传机制;如果因为网络故障该段无法发到对方,UDP 协议层也不会给应用层返回任何错误信息。
- 面向数据报:不能够灵活的控制读写数据的次数和数量。
面向数据报
- 应用层交给 UDP 多长的报文,UDP 原样发送,既不会拆分,也不会合并。
- 数据只能整条交付给应用层,传输不够灵活,但是也不会产生粘包。
- udp数据包的理论长度是多少,合适的udp数据包应该是多少呢?从TCP-IP详解卷一第11章的udp数据包的包头可以看出,udp的最大包长度是216-1的个字节。由于udp包头占8个字节,而在ip层进行封装后的ip包头占去20字节,所以这个是udp数据包的最大理论长度是216-1-8-20=65507。所以理论上当 UDP 发送的数据大于 65507 则这个数据需要用户在应用层进行数据分段;因为 UDP 不会在传输层自动进行数据分段。
UDP 的缓冲区
- UDP 没有真正意义上的发送缓冲区,调用 sendto 会直接交给内核,由内核将数据传给网络层协议进行后续传输动作。
- UDP 具有接收缓冲区,但是这个接收缓冲区不能保证收到的 UDP 报的顺序和发送的 UDP 报的顺序一致;如果缓冲区满了,再到达的 UDP 数据就会被丢弃。
基于 UDP 的应用层协议
- NFS:网络文件系统
- TFTP:简单文件传输协议
- DHCP:动态主机配置协议
- DNS:域名解析协议
问题:用 UDP 怎么实现可靠传输
参考 TCP 的可靠性机制,在应用层实现类似的逻辑:
- 引入确认应答机制,确保对端收到数据。
- 引入序列号/确认序列号,保证数据顺序。
- 引入超时重传,确保接收端一定能收到数据。
叮~?