UDP
→ 返回 计算机网络
UDP(User Datagram Protocol)提供无连接、不保证可靠与有序的报文传输,头部仅 8 字节,由应用层决定是否重传、排序或加密。
TCP 负责「尽量可靠地传字节流」;UDP 负责「尽快把报文送到端口」,适合实时、查询、自建协议。
与 TCP 对比(摘要)
| 特性 | UDP | TCP |
|---|---|---|
| 连接 | 无 | 面向连接 |
| 语义 | 报文边界(message) | 字节流 |
| 可靠性 | 不保证 | 保证 |
| 广播/多播 | 支持(依赖 IP 层) | 不支持 |
| 典型场景 | DNS、QUIC、游戏、监控、RTP | HTTP、数据库、SSH |
UDP 报文格式
┌────────────────────────────────────────────────────┐
│ 源端口(16bit) │ 目标端口(16bit) │
├────────────────────────────────────────────────────┤
│ 长度(16bit) │ 校验和(16bit) │
├────────────────────────────────────────────────────┤
│ 数据(payload) │
└────────────────────────────────────────────────────┘
- 长度: 首部 + 数据(最小 8 字节)
- 校验和: IPv4 下可选为 0(表示不校验);IPv6 通常必须校验
- 无 序号、确认号、窗口、连接状态
适用场景
| 场景 | 为何用 UDP |
|---|---|
| DNS | 单次问答、报文小;超时由解析器重试 → DNS |
| 视频 / 音频(RTP) | 丢旧帧比卡顿重传更可接受 |
| 在线游戏 | 位置包过时即无用,要低延迟 |
| 监控 / 日志(StatsD、Syslog) | 可丢、要高吞吐 |
| DHCP / NTP / SNMP | 广播或极简请求 |
| QUIC / HTTP/3 | 在用户态实现可靠性与多路复用 |
| WebRTC 媒体 | 实时传输,配合 SRTP |
| VPN(WireGuard 等) | 基于 UDP 封装 |
编程要点
无连接 sendto / recvfrom
sendto(sock, buf, len, 0, (struct sockaddr*)&peer, addrlen);
recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr*)&from, &fromlen);已连接 UDP(connect)
对固定对端 connect() 后可用 write/read,内核只接受该对端报文,错误由 ICMP 不可达反馈(异步)。
缓冲区与丢包
接收缓冲区满时,后续报文直接丢弃(无 TCP 式背压):
# Linux 查看/调大 UDP 接收缓冲(示例)
sysctl net.core.rmem_max
sysctl -w net.core.rmem_default=262144应用应自行处理:序列号、ACK、限速、FEC(前向纠错)。
大于 MTU 的报文
UDP 总长超过路径 MTU 会触发 IP 分片;任一分片丢失则整包作废。QUIC、游戏协议通常控制在 < 1200 字节(贴近常见路径 MTU 减头部)。
广播、多播与单播
| 类型 | 说明 |
|---|---|
| 单播 | 一对一,最常见 |
| 广播 | 同一子网内所有主机(如 DHCP Discover) |
| 多播(Multicast) | 订阅组播组的主机接收(IPTV、部分发现协议) |
TCP 无法做广播/多播;需 UDP + IP 多播地址(224.0.0.0/4)。
NAT 与 UDP 打洞
NAT 表项有超时(常见 30s~几分钟)。无长连接时,外网无法主动连入内网主机。
UDP 打洞(Hole Punching): 双方先向公网协调服务器发包,让 NAT 建立映射,再尝试互发 UDP,用于 P2P 游戏、语音。
与 TCP 穿透相比,UDP 状态简单但无内置可靠,需应用协议补齐。
DNS over UDP
- 查询通常 UDP 53,响应 > 512 字节(传统)或触发 TC 标志时改 TCP 53
- 现代 EDNS0 允许更大 UDP 响应,减少 TCP 回退
QUIC 与 HTTP/3
QUIC 在 UDP 之上于用户态实现:
- 可靠传输、加密(TLS 1.3 内置)
- 多流独立确认,避免 TCP 队头阻塞(HTTP/2 单连接丢包拖慢所有流)
- Connection ID:Wi-Fi ↔ 蜂窝切换时可保持连接语义
- 常见端口 UDP 443
HTTP/1.1、HTTP/2 HTTP/3
──────────────── ─────────────
TCP + TLS + HTTP UDP + QUIC(含 TLS 1.3)+ HTTP/3
| 对比 | TCP + TLS | QUIC |
|---|---|---|
| 握手 RTT | 常 2+ RTT | 常 0–1 RTT(含恢复) |
| 队头阻塞 | 单连接丢包阻塞所有流 | 流级别 |
| 内核演进 | 依赖 OS 升级 | 用户态库快速迭代 |
浏览器与 CDN 已广泛支持 HTTP/3;抓包看到的是 UDP,需 QUIC 解析器才能读明文(密钥在端上)。
与「长连接」的说法
口语「UDP 长连接」多指:长时间向同一对端持续发 UDP 报文(如游戏、QUIC),并非 TCP 那种带状态机的「连接对象」,而是 NAT 映射 + 应用层会话保持。
全双工实时通道见 WebSocket(底层仍是 TCP)或 WebRTC / QUIC。
诊断
ss -unap
ss -u -a | head
# 按端口统计 UDP
ss -u -n sport = :53
tcpdump -i eth0 udp port 53 -w dns.pcap| 现象 | 可能原因 |
|---|---|
| 间歇性丢消息 | 接收缓冲小、CPU 忙、链路拥塞 |
| DNS 超时 | UDP 丢包未重试、防火墙拦 53 |
| QUIC 不通 | UDP 443 被拦、中间盒 QUIC 阻断 |
常见 UDP 端口
| 端口 | 用途 |
|---|---|
| 53 | DNS |
| 67/68 | DHCP |
| 123 | NTP |
| 161 | SNMP |
| 443 | QUIC / HTTP/3 |
| 51820 | WireGuard(示例) |