4. UDP协议详解

聊完TCP,咱们来看看它的“老对手”——UDP。

说实话,我刚开始做网络编程时,总觉得UDP像个“野孩子”。不建立连接,不保证送达,甚至连个确认都没有。这能靠谱吗?

后来在一个实时音视频项目里,我才真正理解了它的价值。你想想看,视频通话时如果丢了一帧画面,你是愿意让它卡住等重传,还是直接跳过继续播?答案很明显。

4.1 UDP报文格式:简单到令人发指

UDP的报文头,是我见过最简洁的协议头之一。一共就8个字节,四个字段,每个字段2字节。

字段 长度 说明
源端口号 16位 发送方的端口,可选(可为0)
目的端口号 16位 接收方的端口,必须填写
UDP长度 16位 头部+数据的字节数,最小8
校验和 16位 可选,为0表示不校验

嗯,这里要注意。UDP的校验和是可选的。这在TCP里绝对不可能,但在UDP里,你可以选择不校验。为什么?为了速度。

核心要点:UDP头部固定8字节,没有任何选项字段。这就是它快的原因之一——处理逻辑简单到极致。

我曾经在调试一个嵌入式设备时,发现UDP包总是被丢弃。查了半天,原来是校验和字段填错了。虽然UDP允许校验和为0,但有些路由器会直接丢弃校验和错误的包。这个坑,我踩过。

4.2 UDP的特点:无连接、不可靠、但快

UDP的特点,说白了就是三个词:无连接、不可靠、速度快。

  • 无连接:发数据前不需要握手,直接开干。节省了建立连接的时间。
  • 不可靠:不保证送达,不保证顺序,不保证不重复。发出去就不管了。
  • 速度快:没有拥塞控制,没有重传机制,没有流量控制。就是莽。

你可能会问:这么不靠谱的协议,为什么还在用?

原因很简单:有些场景下,速度比可靠性更重要。

我的经验:在游戏开发中,UDP几乎是标配。尤其是FPS游戏,玩家扣动扳机的那一刻,子弹必须立刻飞出去。如果用TCP,等握手确认完,人早被对手打死了。

4.3 UDP的适用场景:什么时候该用它?

我个人习惯把UDP的适用场景分成三类:

  1. 实时性要求高的场景:音视频通话、直播、在线游戏。丢一帧可以忍,卡顿不能忍。
  2. 简单查询场景:DNS查询、DHCP、NTP时间同步。一次请求一次响应,没必要建立连接。
  3. 广播/多播场景:UDP天然支持广播和多播,TCP做不到。

举个例子。DNS查询用的就是UDP。你访问一个网站,浏览器先发一个UDP包问DNS服务器:“这个域名对应的IP是多少?”服务器回一个UDP包告诉你答案。整个过程几十毫秒搞定。

如果用TCP呢?先三次握手,再发查询,再等响应,再四次挥手。光握手就多花一个RTT,不值当。

避坑指南:我曾经在一个物联网项目里用UDP传输传感器数据。结果发现,当网络拥堵时,丢包率高达30%。后来加了应用层的确认重传机制,才解决问题。记住:UDP不保证可靠,但你可以自己在应用层实现可靠性。

4.4 UDP与TCP的对比:一张表说清楚

很多初学者搞不清什么时候用TCP,什么时候用UDP。我整理了一张对比表,你一看就明白。

对比项 TCP UDP
连接方式 面向连接,需三次握手 无连接,直接发送
可靠性 可靠,有确认重传 不可靠,不保证送达
顺序性 保证数据按序到达 不保证顺序
速度 较慢,有拥塞控制 快,无拥塞控制
头部大小 20-60字节 固定8字节
适用场景 文件传输、网页、邮件 音视频、游戏、DNS

你看,TCP和UDP没有谁好谁坏,只有谁更适合。就像螺丝刀和锤子,你不能说锤子比螺丝刀厉害,得看你要干什么。

4.5 UDP的核心逻辑:一张SVG图看懂

下面这张图,是我自己画的UDP通信流程。简单,但核心逻辑都在里面了。

发送端 应用层数据 ↓ 添加UDP头部 UDP报文(8字节头+数据) 网络 无连接 不保证送达 不保证顺序 无拥塞控制 接收端 收到UDP报文 ↓ 去除UDP头部 应用层数据 UDP通信流程:发送端直接丢包到网络,接收端收到就处理,收不到拉倒

这张图你看懂了吗?发送端把数据封装成UDP报文,直接扔到网络里。接收端能收到就处理,收不到...那就收不到吧。没有确认,没有重传,就是这么干脆。

总结一下:UDP是典型的“快糙猛”协议。它把可靠性交给了应用层,自己只负责一件事——以最快的速度把数据发出去。选不选它,取决于你的业务能不能容忍丢包。

可可精品资料库