0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│ Source Port │ Destination Port │
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│ Length │ Checksum │
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│ Data │
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
字段说明:
- 源端口(16bit):发送方端口号
- 目的端口(16bit):接收方端口号
- 长度(16bit):UDP 报文段总长度(首部+数据),最小 8 字节
- 校验和(16bit):校验 伪首部+首部+数据
伪首部不是 UDP 首部的一部分,只用于校验计算
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│ Source IP Address │
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│ Destination IP Address │
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│ Zero │Protocol│ UDP Length │
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
字段说明:
- 源 IP 地址(32bit):来自 IP 头
- 目的 IP 地址(32bit):来自 IP 头
- 全 0(8bit)
- 协议号(8bit):17(UDP)
- UDP 长度(16bit):来自 UDP 首部的长度字段
二进制反码求和:两个 16 位数相加,若有进位则回卷到最低位,即 $(a + b) \bmod 2^{16} + (a + b) / 2^{16}$。
伪首部: 0x C0A8 0164 0A00 0001 00 11 000C
UDP首部: 0x 0050 0035 000C 0000
数据: 0x 1234 5678
步骤1: 校验和字段置0
步骤2: 数据已是16位整数倍
步骤3-4: 反码求和
C0A8 + 0164 = C20C
C20C + 0A00 = CC0C
CC0C + 0001 = CC0D
CC0D + 0011 = CC1E
CC1E + 000C = CC2A
CC2A + 0050 = CC7A
CC7A + 0035 = CCAF
CCAF + 000C = CCB3
CCB3 + 0000 = CCB3
CCB3 + 1234 = DEE7
DEE7 + 5678 = 355F + 1 = 3560
步骤5: 取反码 = CA9F
接收方:
1. 将 伪首部 + UDP 首部 + 数据 每 16 位一组
2. 按二进制反码求和
3. 结果取反码
4. 如果结果为 0 → 校验通过
5. 如果结果非 0 → 校验失败,丢弃
| 特性 | IP 校验和 | UDP 校验和 |
|---|---|---|
| 校验范围 | 只校验 IP 头 | 伪首部 + UDP 头 + 数据 |
| 每跳计算 | 是(TTL 变化) | 否 |
| 伪首部 | 无 | 有 |
| 是否必须 | 必须 | 可选(IPv4),必须(IPv6) |
| 考点 | 说明 |
|---|---|
| 伪首部的组成 | 源 IP、目的 IP、0、协议号、UDP 长度 |
| 校验和计算 | 反码求和(进位回卷) |
| 为什么需要伪首部 | 验证 IP 地址和协议 |
| UDP 校验是否必须 | IPv4 可选,IPv6 必须 |
↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。