TCP 拥塞控制(Congestion Control)是 TCP 协议中为了防止网络过载而设计的一套机制。
如果说"流量控制"是为了防止接收方 被撑死,那么"拥塞控制"就是为了防止**网络链路(路由器、交换机)**被堵死。它的核心思想是:发送方通过探测网络的承载能力,动态调整发送速率,在保证不压垮网络的前提下,尽可能最大化地利用带宽。
TCP 拥塞控制主要依赖四个核心算法,我们可以把它们看作是一场"交通流量管理"的完整流程:慢启动 (试探路况)、拥塞避免 (平稳加速)、快重传 (事故报警)和快恢复(快速疏通)。
核心变量:拥塞窗口 (cwnd)
拥塞控制的核心是一个叫做拥塞窗口(cwnd, Congestion Window)的状态变量。它代表了发送方根据网络拥塞程度估算出的、自己"最多能发多少数据"的限制。
发送方最终的实际发送窗口,是由接收方的处理能力(rwnd)和网络的承载能力(cwnd)共同决定的,取两者的最小值:
实际发送窗口 = min(接收窗口rwnd, 拥塞窗口cwnd)拥塞控制的所有算法,本质上都是在调整
cwnd的大小。
四大核心算法
1.慢启动 (Slow Start) ------ "快速试探"
当 TCP 连接刚建立时,发送方对网络的带宽和拥塞状况一无所知。为了避免一上来就发送大量数据导致网络拥塞,它会从一个很小的
cwnd开始"试探"。
- 初始值 :
cwnd通常初始化为 1 个 MSS(最大报文段长度)。- 指数增长 :每收到一个 ACK 确认,
cwnd就增加 1 个 MSS。这意味着在一个往返时间(RTT)内,cwnd的大小会翻倍(1 -> 2 -> 4 -> 8...),呈现指数级增长。- 为什么叫"慢"启动?:这个名字其实有些误导。它并不慢,只是起点低,增长速度极快,目的是为了迅速探测到网络的可用带宽上限。
- 退出条件 :当
cwnd增长到一个叫做**慢启动阈值(ssthresh)**的数值时,就会切换到"拥塞避免"阶段。
2.拥塞避免 (Congestion Avoidance) ------ "平稳加速"
当
cwnd达到ssthresh后,TCP 认为网络已经接近饱和,不能再指数增长了,需要更谨慎地增加发送量。
- 线性增长 :每个 RTT,
cwnd只增加 1 个 MSS。这意味着增长速度从指数级变为线性增长(1 -> 2 -> 3 -> 4...),增长速度大大放缓。- 目标:让网络流量平稳地接近其真实容量,避免突然的流量洪峰导致拥塞。
3.快重传 (Fast Retransmit) ------ "事故报警"
TCP 通过两种信号来判断网络是否发生了拥塞(即丢包):
- 超时重传(严重拥塞):发送方在重传超时时间(RTO)内没有收到 ACK。这通常意味着网络非常拥堵,数据包在某个路由器被丢弃了。
- 重复 ACK(轻微拥塞) :接收方收到乱序的数据包(例如,收到了包1和包3,但没收到包2),会立即重复发送对包2的 ACK。当发送方连续收到 3 个重复的 ACK 时,它就判定包2丢失了。
快重传算法 就是针对第二种情况:一旦收到 3 个重复 ACK,发送方就立即重传丢失的报文段,而不必傻等 RTO 超时。这大大减少了等待时间,提高了效率。
4.快恢复 (Fast Recovery) ------ "快速疏通"
这是对"快重传"的配套处理。当通过"3个重复ACK"判断发生轻微拥塞时,TCP 认为网络并没有完全堵死(因为还能传回 ACK),所以不必像"超时重传"那样把
cwnd降为 1 从头开始。
- 乘性减 :将
ssthresh的值减半,然后将cwnd设置为新的ssthresh值(即cwnd = ssthresh)。- 直接进入拥塞避免:跳过"慢启动"阶段,直接进入"拥塞避免"的线性增长模式。
核心原则:AIMD
TCP 拥塞控制的整个逻辑可以总结为一个非常经典的原则:加性增,乘性减(AIMD, Additive Increase Multiplicative Decrease)。
- 加性增 (AI) :在"拥塞避免"阶段,每个 RTT 线性地增加
cwnd(加 1 MSS),温和地探测带宽。 - 乘性减 (MD) :一旦检测到拥塞(无论是超时还是快重传),就将
cwnd大幅减小(通常是减半),快速为网络"减压"。
这种"锯齿状"的调整方式,使得 TCP 连接既能高效利用带宽,又能在拥塞时快速退让,保证了整个网络的稳定性和公平性。
流量控制 vs. 拥塞控制
| 对比项 | 流量控制 | 拥塞控制 |
|---|---|---|
| 作用对象 | 点对点(接收方) | 整个网络(路由器、链路) |
| 解决问题 | 接收方处理不过来,缓冲区溢出 | 网络资源过载,导致丢包和延迟 |
| 核心变量 | 接收窗口 (rwnd) | 拥塞窗口 (cwnd) |
| 控制依据 | 接收方通告的窗口大小 | 网络的丢包、延迟等信号 |