UDP 协议简述

110 阅读4分钟

本文只是简单提炼 UDP 协议的一些概念知识,为读者形成大致的理解。若需要了解更详细的内容,推荐翻阅《TCP/IP 详解》一书。

简介

UDP 是一个无连接的面向数据报的传输层协议,应用进程的每个输出都正好产生一个 UDP 数据报,并组装成一份待发送的 IP 数据报。

对于 TCP 这种面向字节流的协议,应用程序产生的数据跟待发送的 IP 数据报并没有对应关系。

UDP 不提供可靠性传输,它只是尽最大努力地将应用程序产生的数据交付出去,但并不保证能到达目的地。

首部

对协议的学习一般从首部开始,理解协议首部中每个 bit 的设计和意义能帮助我们更好的理解协议的其他内容。

image.png

区别于 TCP 的首部,UDP 的首部固定为 8 字节:

  • 源端口和目的端口:各占 2 字节,范围为 0 ~ 65536,这两个值与 IP header 中的 IP Address 组成唯一的 TCP 连接。
  • UDP 长度:指首部 + 数据的字节长度。该字段最小值为 8(0 字节的 UDP 数据报),这个长度字段你是有冗余的。
  • UDP 检验和:
    • 检验和覆盖首部和数据。
    • UDP 的检验和是可选的,不像 TCP 的是必选的。
    • 检验和的计算会先将该字段设为 0,再对所有字节每 16 bits 进行二进制反码求和,结果存入检验和字段。
    • 若 UDP 的数据报长度为奇数字节,在计算前要在最后填充字节 0,填充的字节不会被传输。
    • UDP 数据报包含一个 12 字节长的伪首部,是为计算检验和而设置的。伪首部包含 IP 首部的一些字段,目的是让 UDP 两次检查数据是否正确到达目的地。

IP 分片

虽然我们前面提到,应用程序的每个输出都产生一个 UDP 数据报,并组装成一份 IP 数据报发送。但是,物理网络层一般要限制每次发送数据帧的最大长度。任何时候 IP 层接收到一份要发送的 IP 数据报时,它要进行选路,然后查询该接口的 MTU,将 MTU 与数据报长度进行比较,需要则进行分片。

分片可以发生在发送端主机上,也可以发生在中间路由器上,且已经分过片的数据报有可能会再次进行分片,IP 首部为分片和重新组装提供了足够的信息。

IP 数据报分片后,只有到达最终目的地才由目的端的 IP 层进行重新组装,这样分片的组装过程对传输层是透明的。

若需要进行分片,但 IP 首部中的不分片位为 1,IP 将不对数据报进行分片,而是丢弃并发送一个 ICMP 差错报文给起始端。

被分片的 IP 数据报,每一片都成为一个分组,具有自己的 IP 首部,且在选路时也各自独立,所以这些分片在到达目的端时可能会失序,但 IP 首部中有足够信息让接收端能正确组装这些分片。

IP 分片后,即使只丢失一片数据,也需要重传整个 IP 数据报。因为 IP 协议没有超时重传机制,由更高层负责超时和重传,所以一个分片丢失后,上层在超时后会重发整个报文段,对应一份 IP 数据报,没法只传其中一个分片。且分片操作可能在任何一个中间路由器执行,起始端无法知道数据报是如何被分片的。

MTU

最大传输单元(Maximum Transmission Unit):链路层对数据帧的长度都有一个限制,如以太网的最大值为 1500 字节,不同类型的网络会有些不一样。

如果 IP 层有一个数据报要传,且长度比链路层的 MTU 要大,那么该数据报就要进行分片,每片都小于 MTU。

由于不同类型的网络 MTU 不一样,若两台主机的通信要经过多个网络,此时更重要的是通信路径中的最小 MTU,它被称为路径 MTU。路径 MTU 不是一个常数,而是取决于选择的路由。