1. UDP 协议基础回顾:报文结构、与 TCP 核心区别、不可靠性本质

各位好,我是老赵。做网络排查这么多年,我见过太多人一遇到 UDP 丢包就慌了神。其实,要解决丢包问题,得先搞清楚 UDP 到底是个什么脾气。这一章,咱们就从头捋一捋 UDP 的基础。

1.1 UDP 报文结构:轻量到极致

UDP 的报文头,简单得让人心疼。它只有 8 个字节。你想想看,TCP 光头部就至少 20 字节,UDP 这 8 个字节能干吗?

字段 长度(位) 说明
源端口 16 发送方端口号,可选(可为 0)
目的端口 16 接收方端口号,必填
长度 16 UDP 头部 + 数据的总长度(字节)
校验和 16 覆盖头部和数据,可选(IPv4 下可为 0)

说白了,UDP 就是「我发我的,你收你的」。它不关心对方在不在,也不关心数据到没到。我在项目中遇到过有人把校验和关了,结果数据在传输过程中被静默篡改,排查了整整两天才发现。嗯,这里要注意:虽然校验和可选,但我建议永远不要关掉它。

核心要点:UDP 头部只有 8 字节,没有序号、确认号、窗口、标志位等 TCP 的复杂字段。这就是它「快」的根本原因,也是它「不可靠」的根源。

1.2 UDP 与 TCP 核心区别:一个像快递,一个像挂号信

我经常跟团队里的新人打比方:TCP 是挂号信,UDP 是普通快递。挂号信要签收、要回执、丢了还能追查;普通快递扔门口就走,丢了只能认栽。

具体区别,我整理了一张表,你一看就明白:

对比维度 UDP TCP
连接状态 无连接 面向连接(三次握手)
可靠性 尽最大努力交付,不保证 保证可靠传输(重传、确认)
有序性 不保证顺序 保证字节流顺序
流量控制 无 有(滑动窗口)
拥塞控制 无 有(慢启动、拥塞避免)
头部开销 8 字节 20-60 字节
传输模式 报文边界保留 字节流,无边界

为什么 UDP 没有拥塞控制?因为它压根不关心网络堵不堵。我曾经在一个视频直播项目中,因为 TCP 的拥塞控制导致画面卡顿,换成 UDP 后延迟直接降到 50ms 以内。当然,代价就是偶尔会花屏——这就是不可靠性的代价。

避坑指南:我曾经见过有人用 UDP 传数据库日志,结果丢了几条关键记录,导致数据不一致。记住:需要可靠传输的场景,别用 UDP 裸奔。

1.3 UDP 的不可靠性本质:为什么它「不负责」?

UDP 的不可靠性,说白了就是三个字:不确认。

发送方把数据包扔到网络上,就不管了。它不会问接收方「收到了吗?」,接收方也不会主动说「收到了」。如果中间路由器丢包了,或者接收方缓冲区满了,数据就悄无声息地消失了。

为什么会这样?因为 UDP 的设计哲学是「快」。它把可靠性这个包袱甩给了上层应用。你想想看,如果每个包都要确认、都要重传,那延迟肯定上去了。对于实时语音、视频、游戏来说,丢几个包可以忍,但延迟高了就完全没法用。

我画了一张图,帮你理解 UDP 的「无状态」本质:

UDP 通信模型:无连接、无确认 发送方 只管发,不确认 接收方 收到算,丢包不通知 网络(尽力而为) 可能丢包、乱序、重复 数据包 数据包 ✕ 丢包!无人知晓 无 ACK 核心结论 UDP 不建立连接、不确认、不重传、不控制流量——这就是不可靠性的本质

从图上你能看到,UDP 的通信模型就是一条单行道。发送方把数据丢进网络,接收方能不能收到,全看网络心情。没有握手、没有挥手、没有确认、没有重传。

警告:UDP 的校验和虽然是可选的,但在 IPv6 下是强制的。如果你在 IPv6 环境中关闭了校验和,数据包会被直接丢弃。我曾经踩过这个坑,切记!

1.4 小结:理解不可靠,才能驾驭不可靠

UDP 的不可靠性,不是设计缺陷,而是设计取舍。它把可靠性交给了上层应用,换来了极低的延迟和极小的开销。对于实时通信、DNS 查询、DHCP、视频流等场景,UDP 是无可替代的选择。