Skip to content

TCP拥塞窗口是什么

1. 拥塞窗口如何工作?

拥塞窗口的大小并非固定不变,而是根据网络的实时状况动态调整。其基本调节原则是:

  • 网络通畅时:如果没有检测到拥塞(即能够按时收到确认 ACK),就增大 cwnd,以提高数据发送速率和网络利用率。
  • 网络拥塞时:如果检测到拥塞(通常表现为数据包丢失),就减小 cwnd,以降低数据发送速率,缓解网络压力。

TCP 通过一套复杂的算法来管理 cwnd 的变化,这套算法通常包括四个主要阶段:慢启动(Slow Start)、拥塞避免(Congestion Avoidance)、快速重传(Fast Retransmit)和快速恢复(Fast Recovery)

2. 拥塞窗口的四个控制阶段

这四个阶段共同协作,精细地调节 cwnd 的大小。

2.1 慢启动 (Slow Start)

当 TCP 连接刚建立时,发送方对网络状况一无所知。为了避免一开始就发送大量数据包导致网络瘫痪,它会采用一种保守的探测方式,这个阶段就是“慢启动”。

  • 初始值:连接建立之初,cwnd 被初始化为一个较小的值,通常是 1 个 MSS(Maximum Segment Size,最大报文段大小)。
  • 指数增长:每当发送方收到一个对新数据的 ACK 确认时,cwnd 就会增加一个 MSS。实际效果是,每经过一个往返时间(RTT),cwnd 的大小就会翻倍(指数级增长)。
  • “慢”的误解:慢启动的“慢”指的是初始窗口小,而非增长速度慢。实际上,它的指数增长速度非常快。

2.2 拥塞避免 (Congestion Avoidance)

指数增长不能无限持续,否则很快会占满网络带宽并导致拥塞。为此,需要一个状态变量叫做慢启动阈值(ssthresh

  • 进入条件:当 cwnd 的大小增长到 ssthresh 时,慢启动阶段结束,进入拥塞避免阶段。
  • 线性增长:进入拥塞避免阶段后,cwnd 的增长方式变得更加缓和。不再是指数增长,而是每经过一个 RTT,cwnd 只增加一个 MSS 的大小(加法增大)。这种线性增长的方式可以更温和地探测可用带宽。

2.3 拥塞发生时的处理

当网络中发生数据包丢失时,TCP 会将其视为网络拥塞的信号,并立即采取措施减小 cwnd。丢包的判断主要有两种方式:

  • 超时重传 (Timeout Retransmission):这是网络拥塞的强烈信号。如果发送方在等待一个 ACK 时发生超时,TCP 会认为网络状况非常糟糕。

    • ssthresh 会减为当前 cwnd 的一半。
    • cwnd 会骤降至初始值 1 个 MSS。
    • 发送方重新进入慢启动阶段。
  • 快速重传 (Fast Retransmit):这是相对较弱的拥塞信号。当发送方连续收到三个或以上相同的(重复的)ACK 时,它会认为这个 ACK 对应的序列号之后的数据包很可能丢失了,但网络并未完全瘫痪,因为后续的数据包还能到达接收方。

    • 发送方不等超时计时器结束,立即重传丢失的数据包。
    • 这触发了快速恢复阶段。

2.4 快速恢复 (Fast Recovery)

快速重传触发后,TCP 认为没有必要像超时重传那样 drastic 地将 cwnd 降为 1,因为连续的重复 ACK 表明网络中仍有数据在正常传输。

  • 乘法减小ssthreshcwnd 都会被设置为当前 cwnd 值的一半(乘法减小),而不是直接降为 1。
  • 避免慢启动:之后,TCP 不会进入慢启动阶段,而是直接开始拥塞避免阶段的线性增长。 有些实现中,在收到重复 ACK 时还会临时性地增加 cwnd,以发送新的数据包,尽快填补网络管道。