19.1 TCP 和 UDP 有什么区别?
TCP 和 UDP 是传输层最核心的两个协议,它们为应用程序提供了两种截然不同的数据传输服务。我的理解是,TCP 就像是拨打电话,而 UDP 就像是发短信。
这个比喻贯穿了它们之间的所有核心区别,主要体现在以下四个方面:
1. 连接方式:面向连接 vs. 无连接
- TCP (Transmission Control Protocol) 是面向连接的。
- 就像打电话,在通信之前,双方必须先通过“三次握手”建立一个可靠的连接。通话期间,这个连接会一直维持。通话结束后,还需要通过“四次挥手”来挂断电话,释放连接。
- 这个连接的建立和维护过程,保证了通信双方的状态是同步的。
- UDP (User Datagram Protocol) 是无连接的。
- 就像发短信,你只需要知道对方的号码(IP和端口),就可以直接把信息发送出去。你不需要事先和对方确认“喂,我们准备开始发短信了”。
- 它是一种“发完就不管”的模式,每次发送的数据报(Datagram)都是独立的。
2. 可靠性:可靠 vs. 不可靠
这是两者最本质的区别,也是由第一点决定的。
- TCP 提供可靠的传输。
- 为了保证可靠,TCP 实现了一整套复杂的机制:
- 确认与重传 (ACK & Retransmission):接收方每收到一个数据包,都要向发送方发送一个确认(ACK)。如果发送方在一定时间内没收到确认,就会认为包丢了,并重新发送。
- 有序传输 (Sequencing):TCP 会给每个数据包编上序号,接收方会根据序号进行重组,确保应用程序拿到的是有序的数据流。
- 流量控制 (Flow Control):通过滑动窗口机制,防止发送方发得太快,撑爆接收方的缓冲区。
- 拥塞控制 (Congestion Control):当网络发生拥堵时,主动减慢发送速度,避免加剧网络恶化。
- 为了保证可靠,TCP 实现了一整套复杂的机制:
- UDP 提供不可靠的传输。
- 它只负责把数据尽力地“扔”出去(Best-Effort Delivery),但不保证:
- 数据是否会到达。
- 数据是否会按顺序到达。
- 数据是否会重复到达。
- 它把所有这些可靠性的工作,都交给了上层的应用程序去自己处理(如果需要的话)。
- 它只负责把数据尽力地“扔”出去(Best-Effort Delivery),但不保证:
3. 性能与开销:重量级 vs. 轻量级
TCP 的所有可靠性保障,都是有代价的。
- TCP 是重量级的:
- 头部开销大:TCP 的报文头至少有 20字节,包含了序号、确认号、窗口大小等大量用于维持可靠性的字段。
- 延迟高:三次握手、确认机制、重传机制等都会引入额外的网络延迟。
- UDP 是轻量级的:
- 头部开销小:UDP 的报文头只有固定的 8字节(源端口、目标端口、长度、校验和)。
- 延迟低,速度快:没有握手,没有确认,没有复杂的控制逻辑,传输效率非常高。
4. 数据传输模式:字节流 vs. 数据报
- TCP 是字节流 (Byte Stream) 模式:
- 应用程序发给 TCP 的数据,和 TCP 发送到网络的数据包之间,没有固定的一一对应关系。TCP 可能会把一个大的应用数据块拆分成多个小包发送,也可能把多个小的应用数据块合并成一个大包发送。
- 这会导致所谓的“粘包/拆包”问题,即接收方需要自己处理从数据流中识别出应用层消息的边界。
- UDP 是数据报 (Datagram) 模式:
- UDP 保留了应用层消息的边界。应用程序发送一个数据包,UDP 就原封不动地给它加上头部,然后发送出去。接收方收到的就是一个完整的、边界清晰的数据包。
- 这使得 UDP 的编程模型更简单。
总结与应用场景
总而言之,TCP 和 UDP 的选择,是一个经典的可靠性与性能之间的权衡。
- 选择 TCP 的场景:当数据完整性和顺序至关重要,不容许任何差错时。
- 例如:网页浏览 (HTTP/HTTPS)、文件传输 (FTP)、电子邮件 (SMTP)。这些场景下,丢失一个字节都可能导致整个文件或页面损坏。
- 选择 UDP 的场景:当实时性和速度优先于绝对的可靠性时。
- 例如:在线视频、语音通话、网络游戏。在这些场景下,偶尔丢失一个数据包(比如画面卡一帧、声音断一下)是可以接受的,但如果为了重传一个旧包而导致整个画面卡住,用户体验会非常糟糕。
- 值得一提的是,最新的 HTTP/3 协议,为了解决 TCP 的队头阻塞等问题,已经抛弃了 TCP,转而使用基于 UDP 的 QUIC 协议,并在 QUIC 内部自己实现了可靠传输,这是网络协议发展的一个重要趋势。