TCP的拥塞控制
TCP(传输控制协议)是互联网中保证数据可靠传输的核心协议,而拥塞控制是 TCP 的 “智能交通管理系统”—— 当网络出现拥堵时,它能避免数据 “堵车”,防止网络瘫痪。
一、为什么需要拥塞控制?(通俗理解)
想象你开车从 A 到 B,路上车太多就会堵车。网络中,“车” 就是数据,“道路” 就是网线 / 无线信号。如果发送方不管不顾地发数据,网络设备(路由器、交换机)的缓冲区会被塞满,导致数据丢失、延迟飙升,就像高速路彻底堵死。
拥塞控制的作用:让发送方根据网络 “路况” 动态调整发送速度,既不浪费带宽,又不造成拥堵。
二、拥塞控制的核心原理
TCP 通过拥塞窗口(cwnd) 控制发送速度:
- 拥塞窗口是发送方在未收到确认前,最多能发送的数据量(单位:字节或报文段)。
- 网络越通畅,cwnd 越大(发送越快);网络拥堵时,cwnd 减小(发送变慢)。
发送方实际发送速度还受接收窗口(rwnd) 限制(接收方告诉发送方 “我还能接多少”),最终发送窗口取 cwnd 和 rwnd 的最小值。
三、拥塞控制的四个阶段
TCP(以经典的 Reno 版本为例)通过四个阶段动态调整 cwnd:
慢启动(Slow Start)
- 通俗:刚上高速,慢慢加速,测试路况。
- 专业:初始 cwnd 很小(如 1~2 个报文段),每收到一个确认(ACK),cwnd 就翻倍(指数增长)。
- 限制:当 cwnd 达到 “慢启动阈值(ssthresh)” 时,进入下一阶段。
拥塞避免(Congestion Avoidance)
- 通俗:接近限速,平稳行驶,不再猛加速。
- 专业:cwnd 不再翻倍,而是每收到一轮 ACK(即一个往返时间 RTT)增加 1 个报文段(线性增长)。
- 目的:避免因过快发送导致拥堵。
拥塞发生(Congestion Detection)
- 通俗:发现前方堵车(比如收到 “数据丢失” 的信号),立刻减速。
- 专业:当检测到丢包(如超时未收到 ACK,或收到 3 个重复 ACK),触发拥塞处理:
- 若因超时丢包:ssthresh 设为当前 cwnd 的一半,cwnd 重置为 1,重新进入慢启动。
- 若收到 3 个重复 ACK(表示数据可能只是轻微拥堵,未完全丢失):ssthresh 设为当前 cwnd 的一半,cwnd 设为 ssthresh,直接进入拥塞避免(快速恢复)。
快速恢复(Fast Recovery)
- 通俗:堵车缓解后,慢慢恢复速度,不用从零开始。
- 专业:仅在收到 3 个重复 ACK 时触发,cwnd 从 ssthresh 开始线性增长,减少重新慢启动的时间浪费。
四、如何检测网络拥堵?
- 超时重传:发送方迟迟没收到 ACK,认为数据丢失(严重拥堵)。
- 重复 ACK:接收方收到乱序数据时,会重复发送已收到的最后一个报文段的 ACK,发送方收到 3 个重复 ACK 后,判断为轻微拥堵(数据可能只是延迟,未丢失)。
五、举个例子
假设初始 ssthresh=16,cwnd=1:
- 慢启动:cwnd 从 1→2→4→8→16(达到 ssthresh,进入拥塞避免)。
- 拥塞避免:cwnd 从 16→17→18→…(每 RTT+1)。
- 若此时检测到丢包:
- ssthresh 设为当前 cwnd 的一半(如 18→9)。
- 若为 3 个重复 ACK:cwnd=9,直接进入拥塞避免(9→10→11…)。
- 若为超时:cwnd 重置为 1,重新慢启动(1→2→4→… 直到 9,再进入拥塞避免)。
六、为什么需要这么复杂?
网络状态是动态变化的(比如高峰期拥堵、闲时通畅),拥塞控制通过 “试探 - 调整 - 反馈” 的循环,在 “高效利用带宽” 和 “避免拥堵” 之间找平衡。没有它,网络可能频繁瘫痪,就像没有红绿灯和限速的马路会彻底堵死。