1. UDP 协议基础:什么是 UDP、UDP 与 TCP 的区别、UDP 的应用场景

各位同学,咱们今天正式开始聊 UDP。说实话,我当年刚接触网络编程时,总觉得 UDP 是个「二等公民」——没连接、不靠谱、丢了包也不管。后来在项目中吃了几次亏,才真正理解它的价值。

UDP 的全称是 User Datagram Protocol,用户数据报协议。它位于传输层,跟 TCP 平级。但它的设计哲学完全不同:能发就发,不管收没收到。

1.1 什么是 UDP?一句话说清楚

UDP 是一种无连接、不可靠、面向报文的传输层协议。你想想看,它就像寄明信片——写好地址扔进邮筒,至于对方能不能收到、什么时候收到、收到的顺序对不对,邮局不保证。

具体来说,UDP 做了三件事:

  • 封装:把应用层数据加上 UDP 头部(8 字节),形成 UDP 报文
  • 发送:直接扔给 IP 层,不建立连接,不确认
  • 接收:收到报文后,根据端口号分发给对应应用程序

就这么简单。没有三次握手,没有滑动窗口,没有拥塞控制。说白了,UDP 就是个「快递员只负责揽件,不负责配送结果」的模型。

UDP 报文结构(8 字节头部)

字段 长度 说明
源端口 16 bit 发送方端口号(可选,不需要可填 0)
目的端口 16 bit 接收方端口号
长度 16 bit UDP 头部 + 数据的总长度
校验和 16 bit 可选校验,检测报文是否损坏

嗯,这里要注意:校验和在 IPv4 下是可选的。如果填 0,表示不校验。我在项目中就遇到过,某些嵌入式设备为了省性能,直接把校验和关了。结果网络环境一差,收到一堆乱码数据……后来我强制要求所有设备必须开启校验和。

1.2 UDP 与 TCP 的区别

很多初学者会问:既然 TCP 那么可靠,为什么还要用 UDP?

我的回答是:可靠是有代价的。TCP 为了可靠,做了大量额外工作——连接管理、确认重传、流量控制、拥塞控制。这些工作带来了延迟和开销。

咱们直接看对比表:

对比维度 UDP TCP
连接状态 无连接 面向连接(三次握手)
可靠性 不可靠,不保证送达 可靠,确认重传
有序性 不保证顺序 保证字节流顺序
传输方式 面向报文(保留消息边界) 面向字节流(无边界)
头部开销 8 字节 20~60 字节
传输效率 高,无额外控制 低,有确认和重传
适用场景 实时性要求高,允许丢包 数据完整性要求高

我个人习惯用一个比喻来理解:TCP 是打电话,UDP 是发语音。打电话要拨号、等待接通、通话中不能插嘴、挂断后释放线路——这是 TCP。发语音,你只管录完发出去,对方什么时候听、听不听得到、顺序对不对,你不管——这是 UDP。

我曾经在一个视频监控项目里,最初用了 TCP 传输视频流。结果网络一波动,TCP 开始重传,视频卡成幻灯片。后来换成 UDP,虽然偶尔花屏,但整体流畅度大幅提升。这就是典型的「用可靠性换实时性」。

避坑指南:我曾经在项目中犯过一个低级错误——用 UDP 传输数据库日志。日志丢了就再也找不回来了。后来我改成 TCP,虽然慢了点,但至少数据不会丢。记住:UDP 不保证送达,关键数据别用 UDP。

1.3 UDP 的应用场景

UDP 虽然不可靠,但它在三个领域几乎是「统治级」的存在。我一个个说。

1.3.1 视频流 / 直播

视频流是 UDP 最典型的应用场景。为什么?因为视频的实时性要求极高,但可以容忍少量丢包。

  • 直播推流:RTMP、SRT 等协议底层常用 UDP
  • 视频会议:WebRTC 默认使用 UDP(基于 ICE 打洞)
  • IPTV:组播场景下几乎只能用 UDP

你想想看,看直播时偶尔花一帧,你根本注意不到。但如果因为重传导致画面卡住 2 秒,你肯定骂娘。这就是 UDP 的用武之地。

1.3.2 DNS 查询

DNS 是另一个 UDP 的「铁杆用户」。你每次访问网站,浏览器都要做一次 DNS 查询。这个查询默认使用 UDP 端口 53。

为什么 DNS 不用 TCP?

  • DNS 查询通常只有几十字节,用 TCP 的三次握手太浪费
  • DNS 查询要求快速响应,UDP 的「发完就忘」正好合适
  • 如果查询结果太大(超过 512 字节),DNS 会切换到 TCP

我记得有一次排查网站访问慢的问题,发现是 DNS 服务器把 UDP 查询给丢了。客户端等超时后才重试,每次访问都要多等 5 秒。后来我在客户端配置了多个 DNS 服务器,问题才解决。

1.3.3 游戏 / 实时对战

游戏行业是 UDP 的「重度用户」。尤其是 FPS(第一人称射击)、MOBA(多人在线战术竞技)这类实时对战游戏。

游戏对延迟极度敏感。你开一枪,服务器要立刻知道。如果用 TCP,丢包后重传,等你收到确认时,人早跑没影了。

游戏 UDP 的典型做法:

  • 状态同步:每秒发送 20~60 次玩家位置、动作
  • 丢包容忍:丢一帧位置数据,用插值算法补回来
  • 自定义可靠:在 UDP 之上自己实现可靠传输(比如只重传关键数据)

我曾经参与过一个手游项目,服务器用 TCP 接收客户端的位置更新。结果网络一卡,TCP 队列堵死,所有玩家都瞬移。后来改成 UDP,虽然偶尔有抖动,但整体体验好了很多。

注意:UDP 在游戏中的使用并不简单。你需要在应用层自己处理丢包、乱序、重复等问题。很多游戏引擎(如 Unity、Unreal)都提供了基于 UDP 的可靠传输组件,建议直接使用,不要自己造轮子。

1.4 UDP 核心知识体系

下面这张图总结了 UDP 的核心知识点,我建议你把它记在脑子里:

UDP 协议核心知识体系 UDP 协议 协议特性 无连接 · 不可靠 面向报文 · 低延迟 头部仅 8 字节 应用场景 视频流 / 直播 DNS 查询 实时游戏 与 TCP 对比 无连接 vs 面向连接 不可靠 vs 可靠 低延迟 vs 高开销 核心原则 UDP 用「不可靠」换「低延迟」,适合实时性要求高、可容忍少量丢包的场景

1.5 小结

这一章咱们聊了 UDP 的核心概念。说白了,UDP 就是个「快但不靠谱」的协议。它没有 TCP 那些复杂的连接管理、确认重传机制,所以延迟低、开销小。但也正因如此,它不保证数据一定能送到。

UDP 的三个核心应用场景——视频流、DNS、游戏——都有一个共同特点:实时性优先,丢包可容忍。如果你在做这类项目,UDP 是你的首选。