RFC 768
User Datagram Protocol —— 整份规范只有三页。先读完它,再去看 TCP,才知道“最小传输层”到底省掉了什么。
它保证什么、不保证什么
This protocol provides a procedure for application programs to send messages to other programs with a minimum of protocol mechanism. The protocol is transaction oriented, and delivery and duplicate protection are not guaranteed. Applications requiring ordered reliable delivery of streams of data should use the Transmission Control Protocol (TCP) [2].
注解
UDP 的设计目标是最少机制:给应用一个“把一块数据交给对端端口”的手续,而不是一条可靠管道。原文连着否掉三件事:送达、重复抑制、(对 TCP 而言的)有序字节流。
易误解:“UDP 一定比 TCP 快”。规范没这么说。它只是把可靠性、排序、拥塞控制都推给应用。DNS、DHCP、QUIC、实时音视频用 UDP,是因为它们想自己决定重试与边界,不是因为 8 字节首部有魔力。
用户数据报首部
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| Source | Destination |
| Port | Port |
+--------+--------+--------+--------+
| | |
| Length | Checksum |
+--------+--------+--------+--------+
|
| data octets ...
+---------------- ...
User Datagram Header Format
注解
固定 8 字节:源端口、目的端口、长度、校验和,各 16 bit。没有序号、没有标志位、没有窗口。数据报边界被保留——接收方一次 recv 对应一个 UDP 数据报,不会像 TCP 那样粘成字节流。
易误解:把 UDP 画成“TCP 去掉可靠字段”。更准确的说法是:UDP 只做复用(端口)和可选完整性(校验和)。
端口、长度
Source Port is an optional field, when meaningful, it indicates the port of the sending process, and may be assumed to be the port to which a reply should be addressed in the absence of any other information. If not used, a value of zero is inserted.
[……节选页眉,下接 Destination Port / Length]
Destination Port has a meaning within the context of a particular internet destination address. Length is the length in octets of this user datagram including this header and the data. (This means the minimum value of the length is eight.)
注解
源端口可以为 0:单向通知、不需要回复时合法。目的端口必须结合目的 IP 才有意义——同样是 53,落到不同主机是不同的 DNS 服务。
Length = 首部 + 数据,最小 8。它和 IP Total Length 不是同一个数:IP 总长还包含 20 字节 IPv4 首部。抓包时若 UDP Length 对不上剩余字节,先怀疑截断或分片。
伪首部与“全 0 / 全 1”
Checksum is the 16-bit one's complement of the one's complement sum of a
pseudo header of information from the IP header, the UDP header, and the
data, padded with zero octets at the end (if necessary) to make a
multiple of two octets.
The pseudo header conceptually prefixed to the UDP header contains the
source address, the destination address, the protocol, and the UDP
length. This information gives protection against misrouted datagrams.
This checksum procedure is the same as is used in TCP.
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| source address |
+--------+--------+--------+--------+
| destination address |
+--------+--------+--------+--------+
| zero |protocol| UDP length |
+--------+--------+--------+--------+
If the computed checksum is zero, it is transmitted as all ones (the
equivalent in one's complement arithmetic). An all zero transmitted
checksum value means that the transmitter generated no checksum (for
debugging or for higher level protocols that don't care).
注解
校验和覆盖 UDP 首部 + 数据 + 一份不算在线上长度里的伪首部(源/目的 IP、协议号 17、UDP 长度)。目的:即使交换机/路由器把包送到错误主机,对端也能发现“这不是给我的”。
两个容易考的特例:计算值为 0 时改发 0xFFFF(全 1);发出去是全 0 表示没算校验和。这是 IPv4 的规则。IPv6 上 UDP 校验和原则上必须使用(另有极少例外),不能再靠“填 0 关掉”。
文末写 protocol number 17。IP 首部 Protocol 字段看到 17,才把数据交给 UDP。
抓包对照
Wireshark 里一条 DNS 查询通常显示为 Ethernet / IPv4 / UDP / DNS。展开 UDP,四个字段全部是线上真实字节,没有“虚拟字段”。
- 直接可见:源/目的端口、Length、Checksum。伪首部不在 UDP 字节里,Wireshark 用外层 IP 现算。
- 过滤器:
udp、udp.port == 53、udp.length > 512。 - 长度对不上:看 IP 是否分片(MF/Offset),或抓包点是否截断(snapshot length)。
考点与易错点
- UDP 首部固定 8 字节;Length 含首部,最小为 8。
- 不保证送达、不排序、不去重、无拥塞控制;应用自己决定要不要重试。
- IPv4 校验和可为 0(关闭);计算为 0 时发送 0xFFFF。IPv6 不能随意关闭。
- 校验和算法与 TCP 相同,都加伪首部,防的是“送到错主机还当自己的”。
- 源端口可为 0;目的端口必须放在目的 IP 的语境里理解。
- IP Protocol = 17。不要和 TCP 的 6、ICMP 的 1 记混。