UDP 位于传输层。
在 OSI 七层模型中,它属于第四层;在 TCP/IP 模型中,它和 TCP 一样属于传输层。看上去只是一个基础概念,但在实际排查网络故障时,如果把传输层、网络层和应用层混在一起,很容易找错方向。
我看 UDP 故障时,一般先分清三个对象:应用数据、端口和 IP 地址。应用决定发送什么,UDP 负责端口之间的数据交付,IP 负责把数据送往目标主机。
以应用程序向服务器发送 UDP 数据为例,数据会依次向下封装:
应用数据 → UDP 数据报 → IP 数据包 → 数据链路层帧
其中:
因此,UDP 不负责寻找跨网络的路由,也不负责解析网页内容。它位于应用层和网络层之间,承担的是传输层工作。
如果程序能够解析域名,却收不到 UDP 响应,问题可能出在端口、防火墙、数据包大小或服务端状态,不一定是 DNS 本身有问题。
UDP 提供的是较基础的数据报传输能力。
它的首部固定为 8 字节,只包含:
应用程序调用发送接口后,数据会被交给操作系统网络协议栈。只要本机成功接收了待发送数据,并不代表对端应用已经收到。
这点在排错时非常重要。程序日志里出现“UDP 发送成功”,通常只能说明本地发送调用没有立即报错,不能把它当成远端处理成功的证据。
UDP 不建立连接,也不维护双方的通信状态。协议本身不会保证:
如果业务需要这些能力,就要在应用层补充序号、确认、超时、重传和速率控制。
例如,监控系统用 UDP 上报普通状态数据,偶尔丢一条可能影响不大;但如果用 UDP 上报必须留存的审计记录,又没有确认和补发机制,就容易造成数据缺口。
协议选择必须跟业务后果一起判断,不能只看哪个首部更小。
TCP 同样是传输层协议,但它提供面向连接的可靠字节流。
对比项 | UDP | TCP |
|---|---|---|
通信前握手 | 不需要 | 通常需要 |
数据组织方式 | 独立数据报 | 连续字节流 |
送达确认 | 不提供 | 提供 |
丢包重传 | 不提供 | 提供 |
顺序整理 | 不提供 | 提供 |
流量控制 | 不提供 | 提供 |
拥塞控制 | 不提供 | 提供 |
首部大小 | 8 字节 | 最少 20 字节 |
TCP 通过序号、确认和重传机制处理丢包,通过窗口控制发送速度,并通过拥塞控制适应网络状态。
应用程序因此不必自行解决大部分可靠性问题,但代价是连接状态和协议处理更复杂。遇到丢包时,可靠性机制也可能带来等待。
UDP 没有这些固定机制,应用层可以根据数据的重要程度自行选择处理方式。
UDP 没有连接建立过程,所以不能照搬 TCP 的排查思路。
我通常按下面几个方向检查。
确认发送端配置的目标端口与服务端监听端口一致,还要确认服务端是否监听了正确的网卡地址。
TCP 端口已经放行,不代表相同端口号的 UDP 也已经放行。TCP 和 UDP 是不同的传输层协议,防火墙规则通常需要分别配置。
数据报超过路径 MTU 后可能发生 IP 分片。任何一个分片丢失,都可能导致整个数据报无法重组。
公网环境里,应尽量控制单个 UDP 数据报大小,避免依赖 IP 分片。
如果业务要求消息有顺序,就应增加序号;如果关键数据不能丢,就应增加确认与重传;如果重复处理会产生副作用,还应设置消息标识并去重。
UDP 没有内置的端到端送达确认。需要确认远端处理结果时,必须由应用层返回响应,或者通过其他通道核验。
UDP 的价值不只是首部少了几个字节,而是它没有强制应用采用同一种可靠性策略。
语音、直播和实时游戏中的旧数据可能很快过期。与其等待旧包重传,不如直接使用新数据。应用还可以自行决定只重传关键消息,对普通状态更新允许少量丢失。
QUIC 也是建立在 UDP 之上的协议。它在 UDP 提供的数据报能力上,自行实现可靠传输、拥塞控制、连接管理和加密。这说明 UDP 可以作为更高层传输机制的基础,并不等于只能用于不重要的数据。
UDP 与 TCP 都属于传输层。
TCP 更适合要求完整、按序传输,而且不想自行实现可靠机制的业务;UDP 更适合重视实时性、允许部分丢失,或者希望自行控制传输策略的业务。
真正做技术选型时,不要只问“UDP 和 TCP 谁更快”,而要问:
数据丢失后必须补回来,还是已经过期,可以直接处理下一条?
这个答案比协议标签更接近实际工程需求。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。