Skip to content

TCP 拥塞控制典型计算题

考情分析

TCP 拥塞控制的计算题是 408 大题的常见题型。典型的出题模式:给定初始 cwnd、ssthresh,以及在某些轮次发生的事件(超时或 3 个冗余 ACK),要求写出每一轮的 cwnd 值或画出 cwnd 变化曲线。这类题目只要掌握规则,做题流程是固定的。

考频:★★★★★

拥塞控制规则速查

在做题之前,先把 TCP Reno 的规则整理清楚。408 默认考 Reno。

正常传输时

当前阶段条件cwnd 变化
慢开始cwnd < ssthresh每经过一个 RTT,cwnd 翻倍
拥塞避免cwnd >= ssthresh每经过一个 RTT,cwnd + 1

发生事件时

事件ssthresh 更新cwnd 更新进入阶段
超时cwnd / 21慢开始
3 个冗余 ACKcwnd / 2ssthresh(即 cwnd/2)拥塞避免

注意执行顺序:先更新 ssthresh,再更新 cwnd。这个顺序很重要,搞反就全错了。

关于 cwnd = ssthresh

当 cwnd 恰好等于 ssthresh 时,按哪个阶段执行?不同教材说法不一,但 408 默认:cwnd = ssthresh 时执行拥塞避免(即开始 +1)。做题时注意审题是否有特殊说明。

做题步骤

遇到拥塞控制计算题,按以下步骤操作:

第一步:列出初始参数(cwnd 初始值、ssthresh 初始值)

第二步:从第 0 轮开始,逐轮计算 cwnd

  • 判断当前阶段(慢开始 or 拥塞避免)
  • 应用对应规则计算下一轮的 cwnd
  • 如果本轮发生了事件,先处理事件再计算

第三步:画表格或曲线图

建议画表格,每一行记录:轮次、cwnd、ssthresh、阶段、说明。这样不容易出错。

例题一:TCP Reno 完整计算

题目: TCP 连接使用 Reno 算法,初始 cwnd=1 MSS,ssthresh=16 MSS。在第 14 轮传输结束时收到 3 个冗余 ACK,在第 22 轮传输结束时发生超时。求每一轮的 cwnd 值。

解题过程

阶段一:慢开始(第 0~4 轮)

初始 ssthresh=16,cwnd 从 1 开始指数增长。

轮次cwndssthresh阶段
0116慢开始
1216慢开始
2416慢开始
3816慢开始
41616cwnd = ssthresh

阶段二:拥塞避免(第 4~14 轮)

cwnd = ssthresh = 16,进入拥塞避免,每轮 +1。

轮次cwndssthresh阶段
41616拥塞避免
51716拥塞避免
61816拥塞避免
71916拥塞避免
82016拥塞避免
92116拥塞避免
102216拥塞避免
112316拥塞避免
122416拥塞避免
132516拥塞避免
1426163 个冗余 ACK

阶段三:快恢复 + 拥塞避免(第 14 轮事件处理后~第 22 轮)

第 14 轮结束时收到 3 个冗余 ACK:

  • ssthresh=26/2=13
  • cwnd=13(= ssthresh)
  • 进入拥塞避免
轮次cwndssthresh阶段
151313拥塞避免
161413拥塞避免
171513拥塞避免
181613拥塞避免
191713拥塞避免
201813拥塞避免
211913拥塞避免
222013超时

阶段四:超时后重新慢开始(第 22 轮事件处理后)

第 22 轮结束时超时:

  • ssthresh=20/2=10
  • cwnd=1
  • 回到慢开始
轮次cwndssthresh阶段
23110慢开始
24210慢开始
25410慢开始
26810慢开始
271010cwnd = ssthresh,转拥塞避免
281110拥塞避免

完整 cwnd 变化汇总

轮次: 0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 | 15 16 17 18 19 20 21 22 | 23 24 25 26 27 28
cwnd: 1  2  4  8  16 17 18 19 20 21 22 23 24 25 26 | 13 14 15 16 17 18 19 20 |  1  2  4  8 10 11
                                               3冗余ACK↑              超时↑

例题二:TCP Tahoe 对比

如果把例题一改成 TCP Tahoe,区别在于对 3 个冗余 ACK 的处理方式。

Tahoe 把 3 个冗余 ACK 当作超时处理:

  • ssthresh=cwnd/2
  • cwnd=1
  • 回到慢开始

所以第 14 轮收到 3 个冗余 ACK 后:

  • ssthresh=26/2=13
  • cwnd=1(不是 13!)
  • 回到慢开始
轮次cwnd (Reno)cwnd (Tahoe)区别
1426 (事件)26 (事件)相同
15131Reno 快恢复,Tahoe 慢开始
16142
17154
18168
191713Tahoe 此时才到 ssthresh

Tahoe 的恢复明显更慢——需要经历完整的慢开始阶段才能回到正常水平。这就是 Reno 引入快恢复的意义。

例题三:含 rwnd 限制的综合题

题目: TCP Reno,cwnd=1,ssthresh=8,rwnd=20。第 10 轮超时。求第 0~15 轮的发送窗口大小。

这道题的关键:发送窗口 = min(cwnd, rwnd)

轮次cwndssthreshmin(cwnd,rwnd)阶段
0181慢开始
1282慢开始
2484慢开始
3888拥塞避免
4989拥塞避免
510810拥塞避免
611811拥塞避免
712812拥塞避免
813813拥塞避免
914814拥塞避免
1015815超时
7ssthresh=15/2=7(取整),cwnd=1
11171慢开始
12272慢开始
13474慢开始
14777拥塞避免
15878拥塞避免

这道题中 rwnd=20 始终大于 cwnd,所以发送窗口 = cwnd。但如果 rwnd 很小(比如 rwnd=10),那从第 5 轮开始发送窗口就会被 rwnd 限制在 10。

注意:ssthresh 除以 2 如果不是整数,取整方式要看题目说明。常见做法是向下取整,但有些题目会特别说明。

例题四:吞吐量计算

题目: TCP Reno,cwnd=1,ssthresh=32。假设不发生任何拥塞事件,在前 10 个 RTT 内,发送方总共能发送多少个 MSS 的数据?

这类题目考的不是 cwnd 的最终值,而是所有轮次 cwnd 的累加和

轮次cwnd累计发送量
111
223
347
4815
51631
63263
73396
834130
935165
1036201

前 5 轮是慢开始(cwnd < 32),第 6 轮 cwnd=32=ssthresh 转拥塞避免,之后每轮 +1。

总发送量 = 1+2+4+8+16+32+33+34+35+36 = 201 MSS

这种题要注意:每一轮发送的数据量等于该轮的 cwnd 值(假设每轮都能把窗口用满)。

常见变体题型

除了标准的逐轮 cwnd 计算,还有几种变体需要注意:

变体一:求某一轮的 ssthresh 值

有些题目不直接问 cwnd,而是问"第 X 轮的 ssthresh 是多少"。ssthresh 只在发生事件时才改变,平时保持不变。所以关键是找到最近一次事件时 ssthresh 被设置成了多少。

变体二:给出 cwnd 变化曲线,反推事件

题目给出一段 cwnd 变化曲线(比如先指数增长到 32,然后突然降到 1),要求判断在哪些轮次发生了什么事件。

  • cwnd 突然降到 1:超时
  • cwnd 突然降到某个大于 1 的值:3 个冗余 ACK(快恢复)
  • 指数增长 → 线性增长的转折点:cwnd 到达 ssthresh

变体三:结合传输效率

传输效率=数据传输时间数据传输时间+非数据传输时间

如果题目给了 RTT 和报文段传输时延,需要计算有效吞吐量。这种题不常见,但偶尔出现。

做题模板

遇到拥塞控制计算题,直接画这个表格:

轮次cwndssthresh阶段事件发送窗口
0(初始值)(初始值)慢开始min(cwnd,rwnd)
1...............

然后逐行填写,遇到事件就先处理事件再继续。

易错点

1. 事件发生在"第 X 轮"还是"第 X 轮结束时"

这个措辞很关键。"第 14 轮发生超时"一般理解为第 14 轮传输的数据触发了超时,所以第 14 轮的 cwnd 还是按之前的规则算出来的,事件的影响从第 15 轮开始体现。但有些题目会说"在 cwnd=X 时超时",这种情况直接从该点开始处理。一定要仔细审题。

2. ssthresh 的计算用的是事件发生时的 cwnd

先算 ssthresh = cwnd/2,再设置新的 cwnd。不是用新的 cwnd 来算 ssthresh。

3. 慢开始阶段 cwnd 到达 ssthresh 后的处理

如果慢开始阶段 cwnd 翻倍后恰好等于 ssthresh,那么该轮 cwnd 就是 ssthresh 的值,下一轮开始拥塞避免(+1)。如果 cwnd 翻倍后超过了 ssthresh(比如 cwnd=6,ssthresh=10,翻倍后 cwnd=12>10),通常认为 cwnd 直接取 ssthresh 的值(cwnd=10),然后转拥塞避免。但这个细节在不同教材中有争议,做题时看上下文。

4. Tahoe 和 Reno 的默认选择

408 默认是 Reno,除非题目明确说用 Tahoe。如果题目只说"TCP 拥塞控制"而没指定版本,按 Reno 做。

5. cwnd 的单位

题目中 cwnd 的单位可能是 MSS,也可能是字节。注意审题。大多数 408 题目用 MSS 作为单位。

快速检验方法

做完题后,可以用以下方法检验答案:

检验一:慢开始阶段 cwnd 是否翻倍

慢开始阶段每轮 cwnd 应该是 1→2→4→8→16→...,如果中间出现了不是 2 的幂次方的值(或者不是连续翻倍的),说明某一步算错了。

检验二:事件处理后 ssthresh 是否合理

ssthresh = cwnd/2,所以 ssthresh 一定不超过事件发生时的 cwnd 值的一半。如果算出来 ssthresh 比事件前的 cwnd 还大,肯定错了。

检验三:拥塞避免阶段是否每轮 +1

拥塞避免阶段 cwnd 应该是 ssthresh→ssthresh+1→ssthresh+2→...,如果出现跳跃或翻倍,说明阶段判断错了。

检验四:快恢复后 cwnd 不应该是 1

Reno 算法中,3 个冗余 ACK 后 cwnd = ssthresh(不是 1)。如果 cwnd 降到了 1,只有两种可能:要么是超时事件,要么是 Tahoe 算法。

高频考点清单

  • 慢开始:cwnd 指数增长(每 RTT 翻倍),直到 cwnd = ssthresh
  • 拥塞避免:cwnd 线性增长(每 RTT +1)
  • 超时处理:ssthresh = cwnd/2,cwnd = 1,慢开始
  • 3 个冗余 ACK 处理(Reno):ssthresh = cwnd/2,cwnd = ssthresh,拥塞避免
  • 发送窗口 = min(cwnd, rwnd)
  • Tahoe vs Reno 对 3 个冗余 ACK 的不同响应
  • 逐轮 cwnd 计算的做题流程
  • ssthresh 的更新顺序:先算 ssthresh,再设 cwnd