目录
[3.2每个报文用 sk_buff 结构管理](#3.2每个报文用 sk_buff 结构管理)
[5.UDP VS TCP](#5.UDP VS TCP)
1.UDP报文格式

- 源端口(16位):标识发送端进程,供对方回复时使用,客户端自动填写临时端口
- 目的端口(16位):标识接收端进程,内核据此将报文交付给正确的socket
- 长度(16位):UDP首部加数据的总字节数,最小8(无数据),最大65535
- 校验和(16位):检测报文传输是否损坏,失败则直接丢弃,不通知发送方
2.关键特性
- **无连接:**无需握手建立通道,直接发数据,像寄信一样即发即走
- **不可靠:**不承诺送达、不保证顺序、不避免重复;校验失败直接丢弃,且不通知发送方
- **面向数据报:**发送端一次 sendto 多少字节,接收端必须一次 recvfrom 完整读取同样长度,否则数据会被截断或丢失
(1)正常接收
// 发送端:一次发100字节
sendto(sockfd, buf, 100, ...);
// 接收端:必须一次收100字节,不能分10次每次10字节
recvfrom(sockfd, buf, 100, ...); // 少收则剩余数据丢弃
(2)演示丢弃与截断
发送端: [报文: 100字节]
↓
接收端 recvfrom(50):
[取走50字节(截断)] [剩余50字节被内核丢弃]
↓
结果:后50字节"丢失",无法挽回
(3)追问
问:如果UDP发送端调用两次sendto,分别发100字节和200字节,
接收端调用一次recvfrom且缓冲区足够大,能收到多少字节?
只能收到第一个100字节,因为UDP是报文边界保留的,一次recvfrom对应一个完整的UDP数据报
第二次的200字节需要另一次recvfrom
如果接收缓冲区小于100字节,则数据被截断(Linux下MSG_TRUNC标志可检测)
- 无发送缓冲区: 内核直接将数据打包发送,没有缓冲等待机制;有接收缓冲区,但报文乱序仍会直接向上交付,缓冲区满时新到的报文会被丢弃
- UDP基于套接字接口支持收发方向独立并发,与TCP一样属于全双工通信,无连接特性并不限制其双向传输能力
MTU(最大传输单元) 指网络接口层所能传输的最大数据包大小(不含以太网帧头尾,通常为1500字节)。它决定了IP分片的阈值:超过MTU的数据报会被分片或丢弃(若设置了DF标志),直接影响UDP等传输协议的载荷上限(如UDP实际最大数据需扣除IP首部20字节+UDP首部8字节,即1472字节)
UDP协议规定其长度字段为16位,因此单个UDP报文的最大理论长度为64KB(实际数据最多65507字节);但底层以太网的MTU通常为1500字节,超过此大小的报文会在IP层自动分片传输,分片会显著增加丢包风险(任一分片丢失则整个报文无法重组)并降低传输效率。因此在实际开发中,当应用数据超过约1400字节时,用户需要在应用层自行实现分组和分发机制(如将大块数据拆分为多个小UDP包发送,接收端再重组),以避免依赖IP层分片带来的不可靠性
3.内核实现视角
3.1UDP控制块与8字节头部
// include/uapi/linux/udp.h 的实际内容(简化版)
struct udphdr {
__be16 source;
__be16 dest;
__be16 len;
__sum16 check; // 校验和特殊类型
};
- __be16 明确表示"Big-Endian 16-bit"(网络字节序)
- __sum16 表示校验和字段(有特殊的对齐/访问要求)
- 从概念上 ,这4个字段各占16位,确实等同于
:16位段
UDP首部8字节固定长度以空间换时间
- 固定8字节:解析时无需遍历选项,直接偏移即可定位数据,时间复杂度O(1)
- 无扩展字段:首部结构恒定不变,协议处理 逻辑极简,无状态开销
- 8字节对齐:匹配CPU自然访存宽度,单指令完成首部加载,避免跨缓存行边界
3.2每个报文用 sk_buff 结构管理
计算机网络 之 【TCP协议】(面向字节流、TCP异常情况、保活机制、文件与Socket的关系、网络协议栈的本质)
这期博客有进行讲解
3.3根据目的端口找到对应的socket,交付给上层
4.基于UDP的应用层协议
- NFS: 网络文件系统
- TFTP: 简单文件传输协议
- DHCP: 动态主机配置协议
- BOOTP: 启动协议(用于无盘设备启动)DNS: 域名解析协议
当然, 也包括你自己写UDP程序时自定义的应用层协议
5.UDP VS TCP
| 特性 | TCP | UDP |
|---|---|---|
| 连接性 | 面向连接(三次握手) | 无连接 |
| 可靠性 | 确认、重传、有序 | 不保证 |
| 流量/拥塞控制 | 有 | 无 |
| 速度 | 相对慢 | 快 |
| 连接迁移能力 | 不支持(IP/端口变化需重连) | 可支持(如 QUIC) |
| 协议状态 | 有 | 无 |
传输层协议状态:
- TCP 的"有状态"是指:内核为每个连接维护序列号、窗口等(传输层对连接的状态记忆)
- UDP 的"无状态"是指:内核不维护上述信息,每个包独立处理(应用层对用户请求的独立处理)
应用层的"业务/会话状态"
- HTTP 的无状态,指的是:服务器默认不记住上一次请求的任何用户信息
- 工程上可通过 Cookie + Session 在应用层模拟出状态
不能简单说 TCP 优于 UDP,要看场景
| 场景 | 选型建议 |
|---|---|
| 文件下载、网页、邮件 | TCP(可靠、有序) |
| 视频直播、VoIP、游戏 | UDP(低延迟,允许丢包) |
| 内网广播、DNS查询 | UDP |
| 需要可靠但不想重传复杂逻辑 | 在UDP上自己实现可靠机制(如QUIC) |
TCP 是"通用稳定"的基础设施,UDP 是"高性能/可控"的工程选择