UDP

了解 UDP 的概念和应用,对比与 TCP 的不同,可能在选择题中考察。

UDP 数据报

Source Port (16)
Data
Destination Port (16)
Checksum (16)
Length (16)
Bit 0
Bit 15
Bit 16
Bit 31
8 Bytes
UDP Header

UDP(User Datagram Protocol)首部的长度固定为 8 个字节(64 位),不论 UDP 携带的数据量大小如何,其首部都保持不变。UDP 首部的各个字段如下:

  • 源端口(Source Port):占用 2 个字节(16 位),用于标识发送方应用程序的端口号。
  • 目标端口(Destination Port):占用 2 个字节(16 位),用于标识接收方应用程序的端口号。
  • 长度(Length):占用 2 个字节(16 位),指示 UDP 数据报的总长度,包括首部和数据。因此,最小长度为 8 字节。
  • 校验和(Checksum):占用 2 个字节(16 位),用于检测 UDP 数据报在传输过程中是否受到损坏。

当传输层从 IP 层收到 UDP 数据报时,就根据首部中的目的端口,把 UDP 数据报通过 相应的端口,上交最后的终点一一应用进程,如下图所示:

端口 1
端口 2
端口 3
UDP 分用
IP 层
UDP 数据报到达

若接收方 UDP 发现收到的报文中的目的端口号不正确(即不存在对应于端口号的应用进程),则就丢弃该报文,并由 ICMP 发送“端口不可达”差错报文给发送方。

UDP 校验

UDP 的校验和(checksum)用于检测数据在传输过程中是否发生错误。它覆盖 UDP 头部、数据部分以及部分 IP 头部信息(伪头部),确保数据的完整性。

这种简单的差错检验方法的校错能力并不强,但它的好处是简单、处理速度快。

发送端

UDP 的发送方需要计算 checksum 字段的值,并且填充进 UDP 首部相应字段中。 发送方计算 checksum 包含构造伪首部、组合校验数据、计算 16 位和、按位取反四个步骤。

源 IP 地址
目的 IP 地址
0
17
UDP 长度
伪首部
源端口
目的端口
长度
校验和
首部
数据
4
4
1
1
2
字节
字节
12
2
2
2
2
UDP 数据报
  1. 构造伪头部

为了确保源和目的地址的正确性,UDP 校验和包含一个伪头部(不实际传输,仅用于计算)。伪头部包括:

  • 源 IP 地址(32 位,IPv4)
  • 目的 IP 地址(32 位,IPv4)
  • 协议字段(8 位,UDP 为 17)
  • UDP 长度(16 位,UDP 头部+数据的总字节数)
  • 填充位(8 位,通常为 0,确保伪头部长度为 12 字节)
  1. 组合校验数据

将以下内容按 16 位分组:

  • 伪头部
  • UDP 头部(包括源端口、目的端口、长度、校验和字段,校验和字段初始置 0)
  • 数据部分(若数据长度为奇数字节,末尾补 0 凑成 16 位)
  1. 计算 16 位和
  • 将所有 16 位数逐一相加,记录进位。
  • 如果有进位(和超过 16 位),将进位加到低 16 位(称为 回卷)。
  • 例如:若两个 16 位数相加得 1 0000 0000 0000 0001,则取低 16 位 0000 0000 0000 0001 并加 1,得 0000 0000 0000 0010
  1. 按位取反
  • 对最终的 16 位和按位取反(0 变 1,1 变 0),得到校验和。
  • 将此校验和填入 UDP 头部的校验和字段。
  1. 特殊情况
  • 如果校验和计算结果为全 0,则发送 1111 1111 1111 1111(全 1),以避免与“校验和禁用”(全 0)混淆。
  • UDP 校验和是可选的,若不使用,校验和字段置为全 0。

注意

  1. 检验时,若 UDP 数据报部分的长度不是偶数个字节,则需填入一个全 0 字节进行填充

  2. 若 UDP 检验和检验出 UDP 数据报是错误的,则可以丢弃,也可以交付给上层,但是需要附上错误报告,即告诉上层这是错误的数据报。

  3. 计算 16 位和的过程中,如果有进位,不要忘记 “回卷”。

接收端

接收端通过以下步骤验证数据完整性:

  1. 提取校验数据:接收端同样构造伪头部(使用接收到的 IP 头部信息),并提取伪首部、UDP 首部(包括接收到的校验和)、数据部分。
  2. 计算 16 位和:将所有 16 位数(包括接收到的校验和)相加,记录并回卷进位。如果数据无误,和的结果应为 1111 1111 1111 1111(全 1)。
  3. 验证结果
    • 如果最终和为全 1,说明数据正确,无错误。
    • 如果和不为全 1,说明数据在传输中发生错误,接收端通常丢弃该数据报(UDP 不负责重传)。
  4. 处理特殊情况
    • 如果接收到校验和为全 0,表示发送端禁用了校验和,接收端可直接接受数据(不校验)。
    • 如果校验和为全 1,需按上述步骤验证。

实例

假设我们要发送一个 UDP 数据报,相关信息如下:

  • 源 IP 地址:192.168.1.1(二进制:11000000 10101000 00000001 00000001)
  • 目的 IP 地址:192.168.1.2(二进制:11000000 10101000 00000001 00000010)
  • 源端口:1024(二进制:00000100 00000000)
  • 目的端口:2048(二进制:00001000 00000000)
  • 数据:0x48656C(3 字节,“Hel”)

则得到 16 位组合数据和校验和计算过程如下所示:

192.168.1.1
192.168.1.2
0
17
11
1024
2048
11
全0
数据
数据
数据
0填充
12B
伪首部
8B
UDP 首部
3B 数据
11000000 10101000 →
192.168
00000001 00000001 →
1.1
11000000 10101000 →
192.168
00000001 00000010 →
1.2
00000000 00010001 →
填充 + 协议
00000000 00001011 →
长度 11
00000100 00000000 →
源端口 1024
00001000 00000000 →
目的端口 2048
00000000 00001011 →
长度 11
00000000 00000000 →
校验和 0
01001000 01100101 →
数据 "He"
01101100 00000000 →
数据 "l" + 补0
11000100 11100000 →
16 位和
00111011 00011111 →
校验和

计算得到的校验和为:00111011 00011111(十六进制:0x3B1F)。

当接收端接收到 UDP 数据报是,接收端将所有 16 位数(包括校验和 00111011 00011111)相加:

重复上述加法,最后一步加上校验和:11000100 11100000 + 00111011 00011111 = 11111111 11111111(全 1)

UDP 特点

  • 无连接性:UDP 是一种无连接的协议,这意味着在发送数据之前,发送方和接收方之间不建立连接。每个 UDP 数据报都是独立的,没有先后顺序的要求。
  • 轻量级:UDP 非常轻量级,因为它不涉及连接建立和维护,也不包括复杂的拥塞控制算法。这使得 UDP 非常适用于低延迟和高吞吐量的应用。
  • 无序性:UDP 数据报在传输过程中不保持顺序。这意味着发送方发送的多个 UDP 数据报可能以不同的顺序到达接收方,并且接收方需要自行处理数据的顺序问题。
  • 不可靠性:UDP 不提供可靠性。它不保证数据的传输成功,也不负责重新发送丢失的数据。如果数据在传输过程中丢失或损坏,接收方将不会收到任何通知,并且需要根据应用程序的要求自行处理这些问题。
  • 广播和多播:UDP 支持广播和多播,允许一个 UDP 数据报同时发送到多个接收方。

应用场景

UDP 常用于 一次性传输较少数据 的网络应用,如 DNS、SNMP 等,因为对于这些应用,若采用 TCP,则将为连接创建、维护和拆除带来不小的开销。

UDP 也常用于 对延迟敏感 多媒体应用(如 电子游戏、实时视频会议、流媒体等),显然,可靠数据传输对这些应用来说并不是最重要的, 但 TCP 的拥塞控制会导致数据出现较大的延迟,这是它们不可容忍的。

UDP 不保证可靠交付,但这并不意味着应用对数据的要求是不可靠的,所有维护可靠性的工作可由用户在应用层来完成。应用开发者可根据应用的需求来灵活设计自己的可靠性机制。

比如 HTTP3 中使用的 QUIC 就是在 UDP 的基础上实现的一种可靠传输协议。