UDP协议
- [UDP 报头结构](#UDP 报头结构)
- 端口号
- 校验和
-
- 校验和的作用
- 比特翻转的原因
- 校验和的完整计算流程
-
- [伪首部(Pseudo Header)](#伪首部(Pseudo Header))
- [UDP 校验和是可选的吗?](#UDP 校验和是可选的吗?)
- [CRC 与校验和的关系](#CRC 与校验和的关系)
- [为什么 UDP 不适合传输大包?](#为什么 UDP 不适合传输大包?)
UDP 报头结构
UDP 报头固定为 8 个字节(64 个 bit 位),格式如下:
UDP 报头(8 字节)
源端口号
2 字节
目的端口号
2 字节
长度
2 字节
校验和
2 字节
应用层数据包
| 字段 | 字节数 | 说明 |
|---|---|---|
| 源端口号 | 2 | 发送端的端口号 |
| 目的端口号 | 2 | 接收端的端口号 |
| 长度 | 2 | UDP 报头 + 数据的全长 |
| 校验和 | 2 | 用于错误检测 |
注意:HTTP 的报头是文本格式,而 UDP/TCP/IP 的报头是二进制格式。
端口号
端口号用于标识主机上的具体进程,便于网络通信定位。
端口号范围
- 端口号占 2 个字节(16 bit) ,取值范围:
0 → 65535 - 保留端口 :
0 → 1023(通常留给系统或知名服务使用) - 可用端口 :
1024 → 65535(我们自己写代码时使用)
端口分配方式
| 角色 | 端口分配 |
|---|---|
| 服务器 | 程序员提前指定(固定端口,便于客户端访问) |
| 客户端 | 操作系统自动分配空闲端口(避免冲突) |
客户端
服务器
指定固定端口
如 8080
系统自动分配
空闲端口
校验和
校验和的作用
UDP 校验和不是安全机制 ,而是完整性检测机制。它只回答一个问题:
这包数据在传输过程中有没有被意外损坏?
它不能防止 恶意篡改(因为没有加密),也不能保证数据一定来自声称的发送方(因为没有认证)。
比特翻转的原因
| 原因 | 场景举例 |
|---|---|
| 电磁干扰(EMI) | 电机启动、闪电、高压线附近的网线 |
| 信号衰减 | 网线过长,接收端无法准确判断高低电平 |
| 串扰 | 相邻线缆之间的电磁耦合 |
| 宇宙射线 | 高能粒子击中内存或传输线路,引发比特翻转(在服务器/航天场景更常见) |
| 硬件故障 | 网卡、交换机端口损坏导致间歇性错位 |
| 时钟漂移 | 收发双方时钟不同步,采样点偏移 |
校验和的完整计算流程
是
否
构造伪首部
(源IP + 目的IP + 协议号 + UDP长度)
伪首部 + UDP报头 + 数据
拼成完整校验对象
按 16 位(2 字节)分组
所有 16 位值累加
(溢出回卷,反码加法)
结果取反码
填入 UDP 报头校验和字段
发送到网络
对端接收
同样方式重新计算
计算结果是全 0?
✅ 数据完好
❌ 数据已损坏,丢弃
伪首部(Pseudo Header)
UDP 校验和的计算范围不只是 UDP 报头 + 数据 ,还包含一个伪首部(来自 IP 层的信息):
| 伪首部字段 | 大小 | 说明 |
|---|---|---|
| 源 IP 地址 | 4 字节 | 取自 IP 报头 |
| 目的 IP 地址 | 4 字节 | 取自 IP 报头 |
| 保留字段 | 1 字节 | 全 0 |
| 协议号 | 1 字节 | UDP 固定为 17 |
| UDP 长度 | 2 字节 | 报头 + 数据的长度 |
为什么需要伪首部?
防止 IP 层在路由时出错(比如 IP 地址在传输中被篡改),导致数据送到了错误的主机。加入伪首部后,IP 地址错误也会导致校验失败。
UDP 校验和是可选的吗?
| 协议 | 校验和是否必选 |
|---|---|
| IPv4 | 可选(校验和为 0 表示不使用校验和) |
| IPv6 | 必选(强制要求校验和) |
在 IPv6 中,UDP 校验和字段不能为 0,必须计算。
CRC 与校验和的关系
| UDP 校验和 | CRC | |
|---|---|---|
| 原理 | 反码求和(补码加法 + 取反) | 多项式除法(生成多项式) |
| 计算速度 | 快(硬件友好) | 相对慢但可硬件加速 |
| 检错能力 | 较弱(某些错误模式检测不出) | 很强(能检测连续突发错误) |
| 应用 | UDP / TCP / IP 层 | 以太网帧尾 FCS / 硬盘 / 压缩文件 |
UDP 用的是 校验和(Checksum) ,不是严格意义上的 CRC。但它们的目的相同:检测传输错误。
为什么 UDP 不适合传输大包?
早期在设计传输方案时,对于大的应用层数据包(比如广告数据包),面临两个选择:
| 方案 | 描述 | 优缺点 |
|---|---|---|
| UDP 分包 | 应用层代码将大包拆成多个小 UDP 数据报传输 | 需要大量代码实现分包/组包,验证复杂,工作量大 |
| TCP 传输 | 直接使用 TCP,没有包长度限制 | 实现简单,不容易出错 |
结论:原则上选择简单、不容易出错的方案 → TCP。