什么是网络拥塞?
当网络中的数据流量超过链路或路由器的处理能力时,就会发生:
- 路由器缓存溢出 -> 丢包
- 排队延迟增加 -> 高延迟
- 重传加剧
TCP拥塞控制的目标就是:在不引起网络拥塞的的前提下,尽可能高效的利用带宽
TCP如何感知拥塞?
TCP无法直接知道网络是否拥塞,但它可以通过两个信号简介判断:
- 超时重传:数据包长时间未收到ACK,即可能丢失 -> 严重拥塞
- 收到重复的ACK:对方多次请求同一个序号,即中间可能有包丢失 -> 轻度拥塞
经典拥塞控制算法(四个阶段)

现代 TCP(如 Reno、Cubic)通常包含以下四个阶段:
1. 慢启动(Slow Start)
- 目的:快速探测网络可用带宽
- 规则:
- 每收到一个 ACK,
cwnd += 1 MSS - 实际效果:每轮 RTT,cwnd 翻倍(指数增长)
- 每收到一个 ACK,
- 起点:
cwnd = 初始值(如 10) - 终点:达到 慢启动阈值(ssthresh) 或发生丢包
📈 例子:
cwnd: 1 → 2 → 4 → 8 → 16 …(每 RTT 翻倍)
2. 拥塞避免(Congestion Avoidance)
- 目的:谨慎增加发送速率,避免触发拥塞
- 规则:
- 每收到一个 ACK,
cwnd += 1/cwnd - 实际效果:每 RTT,cwnd 增加 1 MSS(线性增长)
- 每收到一个 ACK,
- 起点:
cwnd >= ssthresh
📉 增长变慢,更“温和”
3️. 快速重传(Fast Retransmit) + 快速恢复(Fast Recovery)
当收到 3 个重复 ACK(表示中间丢了一个包):
快速重传:
- 不等超时,立即重传丢失的包
快速恢复:
ssthresh = cwnd / 2(砍半)cwnd = ssthresh(补偿已发出的包)- 每收到一个重复 ACK,
cwnd += 1(继续发新数据) - 收到新 ACK(确认重传成功)→
cwnd = ssthresh,进入拥塞避免
避免像超时那样直接回到慢启动(性能更好)
4. 超时重传(Timeout)
- 如果发生超时(比重复 ACK 更严重):
ssthresh = cwnd / 2cwnd = 1(或初始值)- 重新进入慢启动
超时意味着严重拥塞,必须大幅降速