TCP可靠传输与流量拥塞控制详解
TCP 作为互联网的核心传输协议,其稳定性与高效性源于三大机制的无缝协同:可靠传输、流量控制与拥塞控制。本文将深入解析这些机制的工作原理,帮助开发者彻底理解 TCP 如何保证数据准确送达,并在复杂的网络环境中动态调整传输速率。
``一、 TCP 的可靠传输机制
TCP 连接建立后,其可靠传输主要依赖于超时重传、确认机制以及滑动窗口。
1. 基础逻辑:超时重传与确认
发送方每发送一个报文段,就会启动一个定时器。
- 正常情况:若在定时器到期前收到接收方的 ACK 确认,则销毁定时器。
- 超时情况:若超时未收到 ACK,则触发重传该报文。
若仅采用“发一个包、等一个 ACK”的方式,效率极低。因此,TCP 引入了滑动窗口机制。
2. 滑动窗口(Sliding Window)
滑动窗口本质上是发送方当前被允许发送但尚未被确认的数据范围,用序号表示。
- 窗口含义:例如窗口大小为 10,意味着发送方可连续发送 10 个数据段。
- 滑动过程:当接收方确认部分数据后,窗口内已确认数据被释放,窗口整体向前移动,允许发送新数据。
- 形象理解:窗口如同一条向前推进的传送带,后方是已确认数据,中间是已发送未确认数据,前方是暂禁发送区域。窗口只向前滑动,永不倒退。

3. 丢包处理策略
当传输中出现丢包时,TCP 通过以下两种方式处理:
(1) 超时重传
发送方发出数据段并启动定时器,若规定时间内未收到 ACK,直接重传。这是最基础的重传机制。
(2) 快速重传(Fast Retransmit)
为了优化对单个包丢失的响应速度,避免等待漫长的超时计时,TCP 引入了快速重传:
- 场景:发送方连续发送包 1, 2, 3, 4, 5,其中包 2 丢失,但 3, 4, 5 成功到达。
- 累积确认:接收方遵循 TCP 累积确认原则,必须按序确认。收到包 3 时发现包 2 未到,不会确认包 3,而是再次发送对包 1 的 ACK(即重复 ACK)。同理,收到包 4、5 时也会发送对包 1 的重复 ACK。
- 触发条件:当发送方连续收到 3 个 对同一个数据包的重复 ACK 时,推断该 ACK 之后的数据包(包 2)极可能丢失。
- 动作:发送方不必等待超时,立即重传包 2。这极大提高了传输效率。

二、 流量控制(Flow Control)
流量控制解决的是点对点的问题,防止发送方发送速度超过接收方应用程序的处理能力,导致接收方缓冲区溢出和数据丢弃。
1. 接收窗口(RWND)
TCP 报文头中包含一个 16 位的 Window 字段,即接收窗口(Receive Window, RWND)。
- 初始协商:连接建立时,接收端告知发送端其缓冲区大小。
- 动态反馈:在传输过程中,接收端每回复一个 ACK,都会在
Window字段中填入当前缓冲区剩余空间。 - 发送调整:发送端根据 ACK 中的
Window值调整自己的发送窗口。
2. 零窗口与探测
- 零窗口(Zero Window):若接收端缓冲区满,
Window值变为 0,发送端必须立即停止发送,否则必然丢包。 - 零窗口探测(Zero Window Probe):为避免连接因零窗口而永久停滞,发送端在收到零窗口通知后启动定时器,定期发送仅含 1 字节数据的探测包。接收端回复当前窗口大小,一旦窗口不为 0,传输立即恢复。

三、 拥塞控制(Congestion Control)
拥塞控制解决的是整个网络的问题。当路由器或链路过载导致大面积丢包时,若 TCP 仍拼命重传,只会加剧拥堵。由于网络本身不会直接反馈“我堵了”,发送端需通过维护拥塞窗口(Congestion Window, CWND) 来试探和推断网络状态。
TCP 拥塞控制算法包含四个阶段:慢启动、拥塞避免、拥塞发生、快速恢复。
1. 阶段一:慢启动(Slow Start)
- 触发条件:连接刚建立,或发生超时重传后。
- 初始状态:CWND 通常初始化为 1 个 MSS(Maximum Segment Size,最大报文段长度,指纯 TCP 数据载荷最大值,不含头部)。
- 增长模式:指数级增长。每收到一个 ACK,CWND 加 1。
- 发 1 个包,回 1 个 ACK,窗口变 2;
- 发 2 个包,回 2 个 ACK,窗口变 4;
- 发 4 个包,回 4 个 ACK,窗口变 8。
- 终止条件:当 CWND 达到预设的慢启动阈值(ssthresh) 时,停止指数增长,进入拥塞避免阶段。
2. 阶段二:拥塞避免(Congestion Avoidance)
- 增长模式:线性增长(加法增大)。
- 算法:每经过一个往返时间(RTT),CWND 只增加 1 个 MSS。
- 目的:小心翼翼试探网络上限,避免过快增长导致拥塞。
3. 阶段三:拥塞发生(Congestion Detected)
当网络无法承受当前负载开始丢包时,发送端收不到 ACK,判定拥塞发生。TCP 根据丢包原因采取不同策略:
情况 A:超时重传(Timeout)
- 含义:定时器超时仍未收到 ACK,说明网络可能已严重瘫痪。
- 处理措施:
- 将慢启动阈值
ssthresh降为当前 CWND 的一半。 - 将 CWND 重置为 1。
- 重新进入慢启动阶段。
- 将慢启动阈值
- 影响:性能大幅下降,俗称“一夜回到解放前”。
情况 B:收到三个重复 ACK(3 Duplicate ACKs)
- 含义:网络仅轻微拥堵,未完全中断。
- 处理措施:进入快速恢复阶段,避免将窗口归零造成的资源浪费。
4. 阶段四:快速恢复(Fast Recovery)
- 处理措施:
- 将
ssthresh降为当前 CWND 的一半。 - 关键点:不将 CWND 归零,而是将 CWND 设置为新的
ssthresh值(即减半后的值)。 - 立即重传丢失的包。
- 若后续收到新的 ACK,说明重传成功,将 CWND 设为新的
ssthresh,并进入拥塞避免阶段。
- 将

总结
TCP 的拥塞控制本质上是一个动态调整的闭环系统,体现了其“既贪婪又克制”的特性:
- 贪婪:始终试图占满可用带宽。
- 克制:一旦发现网络拥堵,立即退让,防止互联网整体崩溃。
正是可靠传输、流量控制与拥塞控制这三大机制的默契配合,使得 TCP 既能支撑微信消息、网上支付等对准确性要求极高的场景,也能适配从家庭宽带到骨干网络的复杂环境,成为互联网中最稳定、最通用的传输协议。