TCP 拥塞控制的核心目标是 让发送方的发送速率匹配网络的承载能力,避免因发送过多数据导致网络拥塞(丢包、延迟飙升、吞吐量下降)。

关键参数先明确:

  • 拥塞窗口(cwnd):发送方根据网络状况动态调整的发送上限,单位是报文段。
  • 慢启动门限(ssthresh):区分「慢启动」和「拥塞避免」的阈值,当 cwnd < ssthresh 时用慢启动,cwnd > ssthresh 时用拥塞避免。

4 大核心算法是慢启动、拥塞避免、快速重传、快速恢复,它们不是孤立的,而是配合工作的完整流程。

一、 慢启动(Slow Start)

1. 触发条件

  • TCP 连接刚建立时;
  • 网络拥塞后(超时丢包)恢复时。

2. 工作机制

  • 初始状态:cwnd = 1(只能一次发 1 个报文段),ssthresh 一般设为较大值(比如 65535 字节)。
  • 增长规则:每收到一个 ACK 确认,cwnd 加 1;每轮(所有发出的报文段都被确认)下来,cwnd 翻倍(指数增长)。例:cwnd=1→发 1 个→收到 ACK→cwnd=2→发 2 个→收到 ACK→cwnd=4→发 4 个……
  • 切换节点:当 cwnd 增长到 ssthresh 时,停止慢启动,转入拥塞避免阶段

3. 核心作用

连接刚建立时,发送方对网络状况一无所知,通过指数增长快速试探网络的承载上限,但不会一直疯长 —— 到阈值就减速。

二、 拥塞避免(Congestion Avoidance)

1. 触发条件

cwnd ≥ ssthresh 时。

2. 工作机制

  • 增长规则:每轮(所有报文段被确认)后,cwnd 加 1(线性增长),不再翻倍。例:cwnd=8→发 8 个→收到 ACK→cwnd=9→发 9 个→cwnd=10……
  • 拥塞判断:如果出现超时丢包,说明网络拥塞了,执行 2 个操作:
    1. ssthresh = cwnd / 2(将门限设为当前拥塞窗口的一半,下次慢启动到这个值就减速);
    2. cwnd = 1(重置拥塞窗口,重新进入慢启动)。

3. 核心作用

避免拥塞窗口指数增长导致网络过载,用线性增长慢慢试探网络的最大承载能力,平衡吞吐量和稳定性。

三、 快速重传(Fast Retransmit)

1. 触发条件

收到 3 个重复的 ACK 确认报文(不是超时丢包)。

重复 ACK 意义:接收方收到了失序的报文段,比如应该收 seq=5,结果收到 seq=6,就会重复发 ack=5,提示发送方「seq=5 丢了」。

2. 工作机制

  • 不等超时计时器到期,立即重传丢失的那个报文段
  • 不把 cwnd 重置为 1,而是直接进入快速恢复阶段。

3. 核心作用

相比「超时重传」,快速重传能减少丢包后的等待时间,降低吞吐量的下降幅度。

四、 快速恢复(Fast Recovery)

1. 触发条件

快速重传之后。

2. 工作机制

  1. 调整门限:ssthresh = cwnd / 2(和超时丢包一样,将门限减半);
  2. 调整拥塞窗口:cwnd = ssthresh + 3(加 3 是因为已经收到 3 个重复 ACK,说明这 3 个报文段已经被接收方收到,网络没那么糟);
  3. 恢复规则:每收到一个重复 ACK,cwnd 加 1;当收到新的 ACK(确认丢包的报文段已重传成功),cwnd = ssthresh,然后转入拥塞避免阶段

3. 核心作用

丢包后不「一刀切」重置 cwnd,而是平滑恢复发送速率,大幅减少拥塞后的吞吐量波动 —— 这是现代 TCP(比如 Reno 版本)的核心优化。

五、 完整流程示例

plaintext

新建连接 → 慢启动(cwnd指数增长)→ 达到ssthresh → 拥塞避免(cwnd线性增长)
→ 收到3个重复ACK → 快速重传 → 快速恢复 → 回到拥塞避免
(或:超时丢包 → ssthresh减半,cwnd=1 → 重新慢启动)

六、 与你的建站需求关联

你搭建「思迈时光」个人网站时,CDN 加速的核心优化点之一就是 TCP 拥塞控制参数

  • CDN 节点会调大初始 cwnd(比如从 1 改成 10),让慢启动阶段更快达到稳定速率,减少网页首屏加载时间;
  • 采用更先进的拥塞控制算法(比如 BBR 算法,替代传统 Reno),基于网络带宽和延迟动态调整 cwnd,进一步提升传输速度。