首页/计算机网络/05-transport/TCP拥塞控制手算详解 🔗 在 Obsidian 中打开
计算机网络 · 05-transport

TCP拥塞控制手算详解

重要度 ⭐⭐计算机网络/传输层
速查
TCP 拥塞控制四大算法:慢启动(每 RTT cwnd 翻倍)、拥塞避免(每 RTT +1 MSS)、快重传(3 个重复 ACK 立即重传)、快恢复(3 个重复 ACK 时 ssthresh=cwnd/2, cwnd=ssthresh)。超时:ssthresh=cwnd/2,cwnd=1 回慢启动;3 个重复 ACK:ssthresh=cwnd/2,cwnd=ssthresh 进拥塞避免。口诀:慢启动翻倍、拥塞避免加一、超时回到 1、重复 ACK 减半

核心概念

TCP 拥塞控制由四个核心算法组成:慢启动拥塞避免快重传快恢复

四个算法

  1. 慢启动(Slow Start):cwnd 从 1 MSS 开始,每收到一个 ACK 使 $cwnd += 1$ MSS(每 RTT 翻倍,指数增长);当 $cwnd \geq ssthresh$ 时转入拥塞避免。
  2. 拥塞避免(Congestion Avoidance):每 RTT 使 $cwnd += 1$ MSS(线性增长);检测到丢包(超时或 3 个重复 ACK)时做相应处理。
  3. 快重传(Fast Retransmit):收到 3 个重复 ACK 时立即重传丢失的报文段(不等超时)。
  4. 快恢复(Fast Recovery):收到 3 个重复 ACK 时,$ssthresh = cwnd/2$,$cwnd = ssthresh$(或 $ssthresh + 3$),直接进入拥塞避免(线性增长);超时时 $ssthresh = cwnd/2$,$cwnd = 1$ MSS,重新进入慢启动。
两点丢包的区别超时说明网络严重拥塞(惩罚更重,cwnd 回到 1);3 个重复 ACK 说明网络尚能送达部分数据(惩罚较轻,cwnd 只减半)。

丢包处理与增长规则

两种丢包情况的处理
事件ssthreshcwnd进入阶段
超时$cwnd/2$1 MSS慢启动
3 个重复 ACK$cwnd/2$$ssthresh$(或 $ssthresh+3$)拥塞避免
cwnd 变化规则总结
阶段增长方式每 RTT 增长量触发切换条件
慢启动指数增长cwnd 翻倍$cwnd \geq ssthresh$
拥塞避免线性增长+1 MSS丢包事件

手算示例

例 1:经典拥塞控制过程

初始 $ssthresh = 16$ MSS,$cwnd = 1$ MSS。实际计算中通常简化为 cwnd 为整数(单位 MSS),每 RTT 计算一次。

RTT阶段cwnd 变化cwnd说明
1慢启动1→22指数增长
2慢启动2→44指数增长
3慢启动4→88指数增长
4慢启动8→1616$cwnd = ssthresh$,转入拥塞避免
5拥塞避免16→1717线性增长
6拥塞避免17→1818线性增长
7拥塞避免18→1919线性增长

假设 $RTT=7$ 时收到 3 个重复 ACK(快重传 + 快恢复):$ssthresh = \frac{19}{2} = 9$(向下取整),$cwnd = 9$(408 通常取 $cwnd = ssthresh$),进入拥塞避免。

RTT阶段cwnd 变化cwnd说明
8拥塞避免9→1010线性增长
9拥塞避免10→1111线性增长

假设 $RTT=9$ 时发生超时:$ssthresh = \frac{11}{2} = 5$,$cwnd = 1$,进入慢启动。

RTT阶段cwnd 变化cwnd说明
10慢启动1→22
11慢启动2→44
12慢启动4→55$cwnd = ssthresh(5)$,转入拥塞避免
13拥塞避免5→66

例 2:408 考试经典题

设 TCP 的 ssthresh 初始值为 12(单位 MSS)。当拥塞窗口 cwnd 上升到 16 时,网络发生超时。求之后的 cwnd 变化过程。

解析:超时前 $cwnd = 16$,说明正处于拥塞避免阶段(已过慢启动)。

超时时$ssthresh = cwnd/2 = \frac{16}{2} = 8$,$cwnd = 1$,进入慢启动。
RTT阶段cwnd
1慢启动1→2
2慢启动2→4
3慢启动4→8
4拥塞避免8→9($cwnd = ssthresh = 8$,转入拥塞避免)
5拥塞避免9→10
6拥塞避免10→11

例 3:3 个重复 ACK 场景

$ssthresh = 8$,$cwnd = 10$(拥塞避免阶段),此时收到 3 个重复 ACK。

处理$ssthresh = \frac{10}{2} = 5$,$cwnd = 5$(快恢复,$cwnd = ssthresh$),进入拥塞避免。
RTT阶段cwnd
1拥塞避免5→6
2拥塞避免6→7
3拥塞避免7→8

手算口诀

  1. 慢启动翻倍,拥塞避免加一
  2. 超时回到 1,重复 ACK 减半
  3. ssthresh 永远是 cwnd 的一半(丢包时)。
  4. $cwnd \geq ssthresh$ 就切换阶段
判定当前阶段①看增长方式:翻倍 = 慢启动,加 1 = 拥塞避免;②看 cwnd 与 ssthresh 的关系:$cwnd < ssthresh$ 为慢启动,$cwnd \geq ssthresh$ 为拥塞避免;③丢包后看 cwnd 是回到 1(超时 = 慢启动)还是减半(重复 ACK = 拥塞避免)。

记忆卡片

四个算法分别是什么?
慢启动(指数)、拥塞避免(线性)、快重传(3 重复 ACK 立即重传)、快恢复(cwnd 减半后线性增长,不回到 1)。
超时 vs 3 重复 ACK?
超时:$ssthresh=cwnd/2$,$cwnd=1$,慢启动;3 重复 ACK:$ssthresh=cwnd/2$,$cwnd=ssthresh$,拥塞避免。
慢启动如何增长?
每 RTT 翻倍(指数)。$cwnd = 1$ MSS 起,k 个 RTT 后 $cwnd = 2^{k}$ MSS;$cwnd \geq ssthresh$ 时切换。
拥塞避免如何增长?
每 RTT 增加 1 MSS(线性),即 $cwnd = cwnd + 1$。
手算时如何确定阶段?
增长方式 + cwnd 与 ssthresh 的关系 + 丢包后去向,三招合一。

交互动画 · 拥塞窗口 cwnd 演化

05101520 ssthresh=16 1234 5678 910111213 RTT cwnd(单位 MSS)
选择一种丢包/增长场景,查看 cwnd 随 RTT 的演化路径(橙色流动高亮)
点击上方按钮开始
曲线:初始 ssthresh=16(虚线),RTT7 起快恢复(cwnd 19→9),RTT9 超时(cwnd 11→1)。

相关知识点

tcp-flow-and-congestion tcp-three-way-handshake tcp-reliable-transmission

↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。