UDP协议详解(与TCP对比)
一、UDP是什么?
UDP(User Datagram Protocol,用户数据报协议)是传输层的另一个重要协议,和TCP是兄弟俩,但性格完全不同。
如果说TCP是个严谨、可靠的”老好人”,那UDP就是个爽快、不管不顾的”急性子”。
1.1 UDP的特点
无连接:
- 发数据之前不需要建立连接
- 想发就发,不用握手
- 就像寄快递,扔出去就不管了
不可靠:
- 不保证数据一定能送到
- 不保证顺序
- 丢了就丢了,不会重传
- 也不会告诉你收到没收到
面向报文:
- 应用层给它多大的报文,它就原封不动发出去
- 不会拆分,也不会合并
- 一次发一个,一次收一个
没有拥塞控制:
- 网络堵不堵它不管
- 该发多少发多少
- 网络差的时候可能会丢很多包,但它不在乎
首部开销小:
- UDP首部只有8个字节
- TCP首部最少20个字节
- 所以UDP更”轻量”
二、UDP的报文格式
UDP的报文格式很简单,就四个字段,每个字段两个字节:
| 字段 | 长度 | 作用 |
|---|---|---|
| 源端口 | 16位 | 发送方的端口号,不需要的话可以填0 |
| 目的端口 | 16位 | 接收方的端口号,这个必须有 |
| 长度 | 16位 | UDP整个报文的长度(首部+数据) |
| 校验和 | 16位 | 检验数据有没有出错,可选的 |
就这么简单,8个字节搞定。
对比一下TCP,TCP首部光固定部分就20个字节,还有一堆选项,最多能到60个字节。
所以UDP在传输小数据的时候,效率更高。
三、UDP vs TCP 核心对比
这俩都是传输层协议,但设计目标完全不同。
3.1 核心区别对比表
| 特性 | TCP | UDP |
|---|---|---|
| 连接性 | 面向连接,三次握手建立 | 无连接,想发就发 |
| 可靠性 | 可靠,保证送达、保证顺序 | 不可靠,丢了就丢了 |
| 传输方式 | 面向字节流 | 面向报文 |
| 拥塞控制 | 有,网络堵了会减速 | 没有,一直按原速度发 |
| 流量控制 | 有,滑动窗口 | 没有 |
| 首部开销 | 最小20字节 | 8字节 |
| 传输效率 | 相对低,因为要确认、重传 | 高,发完就完了 |
| 应用场景 | 文件传输、邮件、网页 | 视频通话、直播、游戏 |
3.2 为什么有了TCP还要有UDP?
既然TCP这么可靠,为什么不都用TCP呢?
因为可靠是有代价的:
- 要确认,就多了很多额外的数据包
- 要重传,就会有延迟
- 要拥塞控制,网络堵的时候就会变慢
有些场景,我们更看重速度和实时性,丢几个包无所谓:
- 打游戏:卡一下比丢几帧更难受
- 视频通话:丢一帧画面,人眼看不出来
- 直播:晚个几秒不如直接丢包继续播
- DNS查询:就一个请求一个响应,丢了大不了重查一次
这些场景用UDP就很合适。
四、UDP的应用场景
虽然UDP不可靠,但它在很多地方都发挥着重要作用。
4.1 实时音视频
视频通话(微信、Zoom):
- 追求的是实时性
- 偶尔丢一帧,画面卡一下,完全可以接受
- 如果用TCP,网络一差就会卡住等重传,反而体验更差
直播:
- 也是一样的道理
- 观众看到的画面晚一点没关系,但不能卡
语音通话:
- 丢几个包,声音可能有点杂音,但总比卡住强
4.2 网络游戏
很多网游都是用UDP的:
- 玩家的操作需要实时传过去
- 偶尔丢一个操作,问题不大,后面的操作会覆盖
- 如果用TCP,网络一卡就全部卡住,游戏体验爆炸
当然,现在很多游戏会在UDP的基础上自己实现一部分可靠传输的机制,重要的数据包(比如击杀、得分)保证送达,不重要的(比如位置同步)丢了就丢了。
4.3 DNS查询
我们上一篇讲的DNS,大部分都是用UDP的:
- 查询请求很小,一个包就够了
- 响应也很小,一个包也够了
- 丢了怎么办?客户端超时了再查一次就是了
- 不需要建立连接,省了三次握手的时间
当然,DNS也支持TCP,当响应数据太大超过一个包的时候,就会用TCP。
4.4 广播和多播
UDP支持广播和多播,TCP不支持。
广播: 给同一个局域网里所有机器发消息
- 比如DHCP分配IP地址,就是用UDP广播
- 你刚连上网,不知道网关是谁,喊一嗓子”谁是DHCP服务器”,整个局域网都能听到
多播(组播): 给一组机器发消息
- 比如网络电视、视频会议
- 一份数据发给多个人,效率高
五、UDP为什么不可靠还这么常用?
很多人刚学网络的时候都会有这个疑问:UDP这么”不靠谱”,为什么还要用它?
5.1 可靠不是免费的
TCP的可靠是靠什么换来的?
- 确认机制:每个包都要回ACK,多了很多流量
- 重传机制:丢了要重发,有延迟
- 排序机制:乱序了要排好序再交给应用层
- 拥塞控制:网络堵了要减速,不能想发多少发多少
这些机制都需要成本:
- 更多的带宽
- 更大的延迟
- 更复杂的实现
5.2 不同场景需求不同
不是所有场景都需要100%可靠。
举个例子:
- 你在看直播,画面偶尔花一下,你可能都注意不到
- 但如果因为等一个丢了的包,整个直播卡住3秒,你肯定受不了
再比如:
- 你在打游戏,你的位置同步包丢了一个,下一个包过来就覆盖了
- 但如果用TCP,网络一卡就全部卡住,游戏直接没法玩了
UDP的哲学是: 能送到最好,送不到拉倒,我尽力了。
这种”尽力而为”的服务,在很多场景下反而更合适。
5.3 可以在UDP上自己实现可靠传输
UDP虽然本身不可靠,但你可以在它的基础上,自己实现需要的可靠机制。
比如:
- 重要的包,你自己加确认和重传
- 不重要的包,发了就发了
- 想要什么功能,自己加什么功能
这样就很灵活,你可以根据自己的需求,在可靠性和性能之间做平衡。
很多游戏、音视频软件都是这么干的,比如WebRTC、QUIC协议,都是在UDP上做文章。
六、常见问题
6.1 UDP会不会丢包?
会,而且很正常。
UDP不保证可靠,所以丢包是预期内的事情。
- 网络拥堵的时候,路由器会直接丢包
- 接收方收不过来,也会丢包
- 传输过程中出错了,也会丢包
用UDP的应用,都要自己处理丢包的情况。
6.2 UDP的包最大能发多大?
理论上,UDP的长度字段是16位的,所以最大是65535字节,减去8字节首部,数据部分最大65527字节。
但实际上不建议发这么大的包。
- IP层有MTU的限制,一般是1500字节
- 超过MTU的话,IP层会分片
- 分片之后,只要有一片丢了,整个包就废了
- 而且分片重组也有开销
所以实际用的时候,UDP的数据部分一般控制在1400多字节比较合适。
6.3 既然UDP快,为什么HTTP不用UDP?
以前HTTP确实都是用TCP的,因为网页需要可靠传输,不能丢数据。
但现在不一样了,HTTP/3就是用UDP的!
Google搞了个QUIC协议,就是在UDP的基础上实现了可靠传输、拥塞控制这些功能,而且比TCP还快。
- 建立连接更快,不用三次握手
- 没有队头阻塞的问题
- 连接迁移更好,手机切WiFi不中断
现在HTTP/3已经标准化了,越来越多的网站都在支持。
所以说,不是UDP不能做可靠传输,而是它把这个选择权交给了应用层。
七、总结
UDP是传输层的一个重要协议,特点就是:
- 无连接:不用建立连接,想发就发
- 不可靠:不保证送达,不保证顺序
- 开销小:首部只有8字节
- 速度快:没有确认、重传这些额外开销
它和TCP没有谁好谁坏,只是适用场景不同:
- 需要可靠传输的,用TCP
- 追求速度和实时性的,用UDP
理解了UDP的特点,你就能明白为什么视频通话、游戏、直播这些应用都要用UDP了。
网络协议的设计,本质上都是在各种特性之间做权衡——没有完美的协议,只有最合适的协议。