TCP vs UDP:传输层两大协议深度对比
在 OSI 七层模型中,传输层负责端到端的数据传输。而 TCP 和 UDP 是该层最核心的两个协议。它们的设计目标完全不同:TCP 追求万无一失,而 UDP 追求极致速度。
1. 核心差异对比表
| 特性 | TCP (传输控制协议) | UDP (用户数据报协议) |
|---|---|---|
| 连接性 | 面向连接(需三次握手) | 无连接(直接发送) |
| 可靠性 | 可靠传输(确认、重传、排序) | 不可靠传输(尽力而为,可能丢包) |
| 传输形式 | 面向字节流(无边界,自动拆包组包) | 面向报文(保留边界,不拆分) |
| 传输效率 | 慢(首部大、有确认机制、拥塞控制) | 快(首部极小、无任何握手开销) |
| 连接数 | 只能是 1对1(点对点) | 支持 1对1、1对多、多对多(广播/组播) |
| 首部开销 | 最小 20 字节,最大 60 字节 | 固定 8 字节 |
2. 深入理解 TCP:可靠性的代价
TCP 像是一个严谨的邮差。为了保证信件(数据)不丢失、不重复且顺序正确,它付出了巨大的努力:
- 确认应答 (ACK):每发一个包,都要等对方说“收到了”。
- 超时重传:等不到“收到了”,就一直重发,直到对方收到为止。
- 流量控制:根据接收方的处理能力,动态调整发送速度(滑动窗口)。
- 拥塞控制:根据网络的拥堵程度,主动降低发送速率,防止网络崩溃(慢启动、拥塞避免)。
- 面向字节流:TCP 把数据看成一连串无结构的字节流。应用层发来的数据可能会被 TCP 拆成多个包发送,也可能把多个小包合并成一个大包(可能会导致“粘包”问题,需要在应用层处理)。
3. 深入理解 UDP:简单的力量
UDP 像是一个飞快跑过的传声员。它不管你听没听到,喊完就走:
- 简单到极致:UDP 首部只有 8 个字节:源端口、目的端口、长度、校验和。
- 无状态:不需要像 TCP 那样维护复杂的连接状态(序列号、确认号、窗口大小等)。
- 无阻塞:UDP 不会因为网络拥塞而主动减慢速度,也不会因为前面的包丢了而停下来等(无队头阻塞)。
- 面向报文:应用层给 UDP 多长的数据,UDP 就原封不动地发出去(可能会导致 IP 层分片)。
4. 场景选型:我该选哪个?
必须选 TCP 的场景:
- Web 浏览 (HTTP/HTTPS):网页内容必须完整,乱序或丢包会导致页面渲染错误。
- 文件传输 (FTP):下载一个软件,哪怕丢了一个字节,整个软件都可能无法运行。
- 邮件传输 (SMTP/POP3):邮件内容必须准确无误地送达。
优先选 UDP 的场景:
- 实时视频通话/会议:网络卡顿时,我们宁愿画面模糊一点(丢包),也不希望画面卡住几秒钟去等重传。
- 在线竞技游戏:在《英雄联盟》或《CS》中,毫秒级的延迟至关重要。旧的坐标包丢了就丢了,新的坐标包马上就会来。
- 域名解析 (DNS):请求非常短,即使丢了重新查一次也比建立 TCP 连接快得多。
- 直播推流:为了保证低时延,通常允许少量的丢包。
5. 总结
- TCP 适合对质量敏感的业务,它牺牲了速度和灵活性,换取了绝对的可靠性。
- UDP 适合对时效敏感的业务,它牺牲了可靠性,换取了极高的传输效率和低延迟。
补充: 现代协议(如 QUIC / HTTP3)正在尝试结合两者的优点:在 UDP 之上,通过应用层代码自己实现类似 TCP 的可靠传输和拥塞控制,从而彻底解决 TCP 固有的“队头阻塞”和“握手延迟”问题。