TCP拥塞窗口是什么
TCP拥塞窗口(cwnd)是TCP协议中拥塞控制机制的核心组成部分。它是一个由发送方维护的状态变量,用来估算在造成网络拥塞之前,可以向网络中发送多少数据。简而言之,cwnd是发送方根据自己感知的网络拥塞程度而动态调整的“发送许可”大小。
为了避免过多的数据注入网络导致路由器或链路过载,TCP发送方在任何时刻的实际发送窗口大小取决于两个因素:拥塞窗口(cwnd)和接收方通告的接收窗口(rwnd)。
发送窗口 (swnd) = min(cwnd, rwnd)
- 接收窗口 (
rwnd):反映了接收方的接收能力,用于流量控制,防止发送方发送的数据量超过接收方缓冲区的处理能力。 - 拥塞窗口 (
cwnd):反映了发送方对网络状况的评估,用于拥塞控制,防止过多的数据包导致网络拥塞。
拥塞窗口如何工作?
拥塞窗口的大小并非固定不变,而是根据网络的实时状况动态调整。其基本调节原则是:
- 网络通畅时:如果没有检测到拥塞(即能够按时收到确认ACK),就增大
cwnd,以提高数据发送速率和网络利用率。 - 网络拥塞时:如果检测到拥塞(通常表现为数据包丢失),就减小
cwnd,以降低数据发送速率,缓解网络压力。
TCP通过一套复杂的算法来管理cwnd的变化,这套算法通常包括四个主要阶段:慢启动(Slow Start)、拥塞避免(Congestion Avoidance)、快速重传(Fast Retransmit)和快速恢复(Fast Recovery)。
拥塞窗口的四个控制阶段
这四个阶段共同协作,精细地调节cwnd的大小。
1. 慢启动 (Slow Start)
当TCP连接刚建立时,发送方对网络状况一无所知。为了避免一开始就发送大量数据包导致网络瘫痪,它会采用一种保守的探测方式,这个阶段就是“慢启动”。
- 初始值:连接建立之初,
cwnd被初始化为一个较小的值,通常是1个MSS(Maximum Segment Size,最大报文段大小)。 - 指数增长:每当发送方收到一个对新数据的ACK确认时,
cwnd就会增加一个MSS。实际效果是,每经过一个往返时间(RTT),cwnd的大小就会翻倍(指数级增长)。 - “慢”的误解:慢启动的“慢”指的是初始窗口小,而非增长速度慢。实际上,它的指数增长速度非常快。
2. 拥塞避免 (Congestion Avoidance)
指数增长不能无限持续,否则很快会占满网络带宽并导致拥塞。为此,需要一个状态变量叫做慢启动阈值(ssthresh)。
- 进入条件:当
cwnd的大小增长到ssthresh时,慢启动阶段结束,进入拥塞避免阶段。 - 线性增长:进入拥塞避免阶段后,
cwnd的增长方式变得更加缓和。不再是指数增长,而是每经过一个RTT,cwnd只增加一个MSS的大小(加法增大)。这种线性增长的方式可以更温和地探测可用带宽。
3. 拥塞发生时的处理
当网络中发生数据包丢失时,TCP会将其视为网络拥塞的信号,并立即采取措施减小cwnd。丢包的判断主要有两种方式:
-
超时重传 (Timeout Retransmission):这是网络拥塞的强烈信号。如果发送方在等待一个ACK时发生超时,TCP会认为网络状况非常糟糕。
ssthresh会减为当前cwnd的一半。cwnd会骤降至初始值1个MSS。- 发送方重新进入慢启动阶段。
-
快速重传 (Fast Retransmit):这是相对较弱的拥塞信号。当发送方连续收到三个或以上相同的(重复的)ACK时,它会认为这个ACK对应的序列号之后的数据包很可能丢失了,但网络并未完全瘫痪,因为后续的数据包还能到达接收方。
- 发送方不等超时计时器结束,立即重传丢失的数据包。
- 这触发了快速恢复阶段。
4. 快速恢复 (Fast Recovery)
快速重传触发后,TCP认为没有必要像超时重传那样 drastic地将cwnd降为1,因为连续的重复ACK表明网络中仍有数据在正常传输。
- 乘法减小:
ssthresh和cwnd都会被设置为当前cwnd值的一半(乘法减小),而不是直接降为1。 - 避免慢启动:之后,TCP不会进入慢启动阶段,而是直接开始拥塞避免阶段的线性增长。 有些实现中,在收到重复ACK时还会临时性地增加
cwnd,以发送新的数据包,尽快填补网络管道。