ACK,SEQ,FIN,RTT
本文最后更新于52 天前,其中的信息可能已经过时,如有错误请发送邮件到184874483@qq.com

TCP 最容易混的几个点上:SYN/FIN 是否占序号seq 和 ack 到底各表示什么挥手时 FIN 到底意味着什么

一、先把最核心的规则捋顺:哪些东西会消耗序列号

TCP 的序列号本质上是给“字节流位置”编号的。通常有两类东西会占用一个序列号:

第一类是真正的数据字节。发送了多少字节数据,就消耗多少个序列号。

第二类是两个特殊控制位:SYNFIN。它们虽然不携带应用层数据,但都要各自占用 1 个序列号。

所以考试里一定要记住下面这三条:

  1. 普通 ACK 报文段如果不携带数据,那么不消耗序列号
  2. SYN=1 的报文段,即使不带数据,也消耗 1 个序列号
  3. FIN=1 的报文段,即使不带数据,也消耗 1 个序列号

这就是为什么大家常说:

数据消耗多少,序号就前进多少;SYN 和 FIN 各额外再加 1;纯 ACK 不加。


二、为什么 SYN 和 FIN 明明“不带数据”却还占一个序号

这不是随便规定的,而是 TCP 协议为了保证连接建立、连接释放也能被可靠确认。

可以把它理解成:

  • SYN:占一个“建立连接”的逻辑位置
  • FIN:占一个“结束发送”的逻辑位置

因此对方确认时,也必须把这一个位置确认掉,所以确认号会加 1。

这正是很多题目的陷阱来源:
不要把“是否带数据”和“是否占序号”画等号。
因为 SYNFIN 就是“不带数据但占序号”的典型例外。


三、第一道例题:如何根据 SYN 和第 4 次挥手求 A 发了多少字节数据

题目是:

主机 A 和 B 之间建立了一个 TCP 连接,A 向 B 发送的第一个 SYN 报文段中的序号值 seq = 211,数据传输结束,在释放连接时,A 向 B 发送的第 4 次挥手报文段的 seq = 985,则在本次通信过程中,A 向 B 总共发送了多少字节的数据?

这题的关键不是“第 4 次挥手”,而是要知道:

  • A 最开始发了一个 SYN
  • A 后面发送了若干数据
  • 如果 A 发的是第 4 次挥手报文段,说明 A 是最后发 ACK 的一方,也就是通常的主动关闭方 A:
    第 1 次挥手 A 发 FIN
    第 4 次挥手 A 再发一个纯 ACK

这里最关键的一点是:

第 4 次挥手是纯 ACK,不消耗序列号。
所以第 4 次挥手的 seq,实际上等于 A 在发送完 FIN 之后“下一个可用序列号”。

分步推

A 发的第一个 SYN:

  • seq = 211
  • 由于 SYN 占 1 个序列号,所以之后 A 的下一个序号变成 212

设 A 总共发送了 x 字节数据,那么数据发完后:

  • 序号前进到 212 + x

然后 A 发送第 1 次挥手的 FIN,FIN 还要再占 1 个序列号,所以发完 FIN 以后:

  • 下一个序号变成 213 + x

而第 4 次挥手是纯 ACK,不消耗序号,因此它的 seq 就应该是:

213 + x = 985

解得:

x = 985 - 213 = 772

结论

A 向 B 总共发送了 772B 的数据。

这类题的通用模板

只要题目从“初始 SYN 的 seq”跳到“后面某个 ACK/FIN 的 seq”,就按下面的式子想:

后面的 seq = 初始 SYN 的 seq + 1 + 数据字节数 + 是否发过 FIN

这里“是否发过 FIN”如果发过,就再加 1。

本题里正好是:

985 = 211 + 1 + 数据字节数 + 1

所以数据字节数就是:

985 - 211 - 2 = 772

易错点

最容易错成 773 或 774,原因一般有两个:

第一种错法:忘了 SYN 占 1。
第二种错法:忘了 FIN 也占 1。
第三种错法:误以为第 4 次挥手那个 ACK 也要占 1,其实纯 ACK 不占。


四、seq 和 ack 到底是什么关系

你提到一句非常关键的话:

同一个报文段中,seq 和 ack 没有任何联系

这个说法在做题意义上,基本可以认为是对的。

1)seq 表示什么

seq 表示:本报文段数据部分的第一个字节的序号

如果本报文段不带数据,但带 SYN 或 FIN,那么它表示的就是这个 SYN 或 FIN 占用的那个序号位置。

所以 seq 看的是“我这边发出去的内容,从哪一个编号开始”。

2)ack 表示什么

ack 表示:我期望收到对方下一个字节的序号

换句话说,ack = 已经正确收到对方的最后一个字节序号 + 1

所以 ack 看的是“我已经收到了你哪儿,你接下来该从哪儿继续发”。

3)为什么说同一个报文段中的 seq 和 ack 没直接关系

因为:

  • seq 是描述自己发出的数据
  • ack 是描述自己已收到对方的数据

二者分别对应两个方向的数据流。

TCP 是全双工的,A→B 和 B→A 的字节流编号是各自独立的。
所以一个报文里的 seqack,本质上是在说两件不同的事。

这正是考研题喜欢考的点:
不要把某个报文的 seq 和 ack 当成一个公式互相去推。

真正能推的是:

  • 对方回复的 ack 往往由我这个报文的 seq + 有效长度 推出来
  • 但同一个报文内部,seqack 不要求存在固定关系

五、第二道题:A 发给 B 的报文 seq=200,ack=201,数据部分 2B,B 的确认报文怎么求

题目:

A 和 B 之间建立了 TCP 连接,A 向 B 发送了一个报文段,其中序号字段 seq=200,确认序号字段 ack=201,数据部分有 2B,那么在 B 对该报文的确认报文段中……

这类题的核心就是求 B 回给 A 的确认信息。

先看 A 发出的报文

A 发给 B:

  • seq = 200
  • 数据长度 = 2B

这说明 A 这次发出去的数据字节序号是:

  • 第一个字节:200
  • 第二个字节:201

所以 B 收到后,下一次期望收到 A 的字节序号就是:

202

因此 B 发回的确认报文段中:

  • 确认号 ack = 202

那 B 的 seq 能不能确定

一般不能单独确定,除非题目还告诉了:

  • B 当前自己的发送序号是多少
  • 或者前面 B 已经发过多少数据
  • 或者是否只是纯 ACK 且初始状态已知

所以这题通常能确定的是:

  • ack = 202

而不是完整唯一确定 seq

为什么 A 报文里的 ack=201 对这一步没影响

因为 A 报文中的 ack=201 表示的是:

“A 已经收到 B 发来的序号到 200 为止的内容,期待 B 下一个从 201 开始发。”

这只是 A 对 B 的确认,和 B 对 A 这次 2B 数据的确认不是同一件事。

这正好再次说明:

一个报文里的 seq、ack 是两个方向上的信息。


六、第三类题:客户先发 FIN,后来收到服务器发来的 FIN,如何判断报文段 B

客户与服务器建立 TCP 连接,当连接断开时,客户先向服务器发送一个标志 FIN=1 的报文段 A,此报文段中 seq 值为 x,ack 值为 y。一段时间后,客户收到了服务器发来的一个标志 FIN=1 的报文段 B,则关于报文段 B 的说法中,

先看报文段 A

客户先发 FIN 报文段 A:

  • FIN=1
  • seq = x
  • ack = y

由于 FIN 要占一个序列号,所以服务器确认这个 FIN 时,应当确认到:

  • x + 1

因此,服务器之后发来的 FIN 报文段 B,通常会满足:

  • ack = x + 1

因为服务器已经收到了客户的 FIN。

那 B 的 seq 是多少

这个不能直接写成某个固定值,取决于服务器在这之前还有没有数据没发完。

分两种常见情况:

情况一:服务器没有额外数据要发

那服务器可能先回一个 ACK,再过一会儿再发 FIN。
此时服务器发 FIN 的 seq 就是它当前自己的下一个发送序号,具体数值取决于服务器之前发了多少数据。

情况二:服务器还有数据没发完

服务器可能先继续把剩余数据发完,最后再发 FIN。
那么这个 FIN 的 seq 就会更大。

所以通常能确定的是:

  • 报文段 B 的 ack = x + 1
  • 报文段 B 的 seq 不能仅凭题干唯一确定

这类题最容易错在哪里

最常见的错法是把服务器发来的 FIN 的 seq 也写成 x+1
这是错误的,因为:

  • x+1 是服务器对客户 FIN 的确认号
  • 服务器自己的 seq 走的是另一套编号

又回到了那句核心话:

seq 看自己,ack 看对方。


七、FIN 到底表示什么:是不是“一发 FIN 就整个连接断了”

你最后那道选择题本质是在考 FIN 的语义。

题目大意:

TCP 的通信双方,有一方发送了带有 FIN 标志的数据段后,表示
A. 将断开通信双方的 TCP 连接
B. 单方面释放连接,表示本方已经无数据发送,但可以接收对方的数据
C. 中止数据发送,双方都不能发送数据
D. 连接被重新建立

正确答案

B

为什么是 B

发送 FIN=1 的含义是:

“我这一边已经没有数据要发了,我的发送方向要关闭了。”

但 TCP 是全双工的,连接有两个方向:

  • A → B
  • B → A

所以一方发 FIN,只是表示本方发送方向关闭,并不代表另一方也立刻不能发了。

也就是说:

  • 发 FIN 的这一方:以后不能再发送数据
  • 但它仍然可以继续接收对方发送的数据

这就叫做半关闭单方向关闭

为什么不是 A

A 说“将断开通信双方的 TCP 连接”,这个说法太绝对了。
发出一个 FIN 以后,连接还没有完全断开,因为对方可能还有数据继续发。

真正完全断开,要等双方都完成各自方向的关闭,也就是通常的四次挥手走完。

为什么不是 C

C 说“双方都不能发送数据”,这明显不对。
一方发 FIN 后,对方仍然可以继续发数据。

为什么不是 D

D 更明显不对,FIN 是释放连接,不是重建连接。


八、把这几个知识点连成一个做题框架

做 TCP 首部字段、握手挥手、seq/ack 题时,我现在更建议按下面这个框架来判断。

第一步:先分清“谁给谁发”

TCP 是双向的,A→B 和 B→A 一定分开看。
只要题目一乱,先在草稿纸上标两个方向。

第二步:看 seq 是谁自己的编号

seq 永远看“本报文发送方”的发送字节流。

也就是:

  • A 发的报文,seq 看 A 自己发到哪儿了
  • B 发的报文,seq 看 B 自己发到哪儿了

第三步:看 ack 是对谁的确认

ack 永远看“本报文发送方已经收到了对方多少”。

也就是:

  • A 发的报文,ack 是 A 对 B 的确认
  • B 发的报文,ack 是 B 对 A 的确认

第四步:判断这次报文会不会让序号加长度

序号前进量 =

数据字节数 + SYN是否为1 + FIN是否为1

其中:

  • 纯 ACK:加 0
  • SYN:加 1
  • FIN:加 1
  • 带 n 字节数据:加 n

第五步:确认号怎么推

ack = 对方下一个应该发送的序号

也就是:

ack = 对方本次报文的 seq + 对方本次报文占用的序号长度

这里“占用的序号长度” again 就是:

数据长度 + SYN是否为1 + FIN是否为1


九、这几类题为什么总容易错

TCP 这一章最容易错,不是因为公式难,而是因为信息是“交叉的”。

同一个报文段里同时出现:

  • 本方的 seq
  • 本方对对方的 ack

于是脑子很容易把两个方向混在一起。

再加上 SYNFIN 这两个“不带数据却占序号”的特例,很多人就会在计算时少加 1 或多加 1。

所以做题时一定要强行养成两个习惯:

第一,分方向
永远把 A→B 和 B→A 分开记。

第二,先算占用长度
每遇到一个报文,先判断它占几个序号:

长度 = 数据字节数 + SYN?1:0 + FIN?1:0

只要这一步不乱,后面的 seqack 基本都能稳住。


TCP 里的 RTT 到底是什么,做题时怎么用

在 408 风格的传输层题目里,RTT 一般指往返时间,也就是一个报文从发送端到接收端,再从接收端返回发送端所经历的总时间。于是有一个最常用的换算:

单程传播时延 = RTT / 2

所以凡是涉及“三次握手、四次挥手、确认到达、最短释放时间”这类题,第一步通常就是把 RTT 先拆成两个 RTT/2 来看。

另外,TCP 题里最常配套考这几条规则:

第一,seq 表示本报文段数据部分第一个字节的序号
第二,ack 表示期望收到的下一个字节序号
第三,TCP 的确认通常是累计确认,中间缺了一段,即使后面的段到了,也不能越过去确认。
第四,发生超时时,按照考研常见模型处理为:

  • ssthresh = 当前cwnd / 2
  • cwnd = 1 MSS
  • 然后重新进入慢开始,达到门限后转入拥塞避免

第五,发送窗口大小不是只看拥塞窗口,还要看接收窗口:

发送窗口 = min(cwnd, rwnd)

下面按题目逐个拆。


第1题:客户主动断开后,服务器最短多久释放连接

题目大意是:

假设 TCP 客户与 TCP 服务器的通信已结束,端到端往返时间为 RTT。
t 时刻 TCP 客户请求断开连接,则从 t 时刻起,TCP 服务器释放该连接的最短时间是多少?

结论

t 时刻起,TCP 服务器最短在 1.5RTT 后释放连接

解题过程

这是标准的四次挥手题,而且问的是“服务器释放连接的最短时间”。

在最短情况下,可以认为服务器一收到客户端的 FIN,就立刻回复 ACK,并且自己也立即发送 FIN。

时间线如下:

第一步:客户端发送 FIN

客户端在 t 时刻发送 FIN。
该报文到达服务器,需要 RTT/2

所以服务器在:

t + RTT/2

收到客户端的断开请求。

第二步:服务器立刻回 ACK,并同时发自己的 FIN

若按最短情况处理,服务器在收到 FIN 的瞬间就可以发出 ACK,并且发出自己的 FIN。

客户端收到服务器发来的 FIN,也需要 RTT/2

所以客户端在:

t + RTT

收到服务器的 FIN。

第三步:客户端对服务器的 FIN 进行确认

客户端收到服务器 FIN 后,立刻发最后一个 ACK。
这个 ACK 再经过 RTT/2 到达服务器。

所以服务器在:

t + 1.5RTT

收到最终确认,正式释放连接。

为什么不是 RTT 或 2RTT

很多人会把“客户端进入 TIME_WAIT 等 2MSL”混进来。题目问的是服务器释放连接的最短时间,不是客户端彻底结束 TIME_WAIT 的时间。

所以答案看的是服务器进入 CLOSED 的时刻,即收到最后 ACK 的时刻,也就是:

1.5RTT


第2题:只收到第1个和第3个段时,确认号是多少

题目大意是:

甲向乙发送了 3 个连续的 TCP 段,分别包含 200B、300B、400B 的有效载荷,第 3 个段的序号为 1000
若乙仅正确接收到第 1 个和第 3 个段,则乙发送给甲的确认序号是多少?

结论

确认序号是:

700

解题过程

已知第 3 个段的 seq = 1000,它前面还有第 2 个段,长度为 300B

所以第 2 个段的起始序号应为:

1000 - 300 = 700

第 1 个段长度为 200B,所以第 1 个段起始序号为:

700 - 200 = 500

于是三个段分别是:

  • 第 1 段:seq = 500,长度 200B
  • 第 2 段:seq = 700,长度 300B
  • 第 3 段:seq = 1000,长度 400B

现在乙只收到了第 1 个和第 3 个,但第 2 个段丢了

TCP 采用累计确认,确认号永远指向“当前按序收到的最后一个字节之后的那个字节”。

乙虽然收到了第 3 段,但因为第 2 段没到,数据不连续,所以只能确认到第 1 段末尾之后。

第 1 段覆盖的字节范围是:

500 ~ 699

因此下一个期望收到的字节序号是:

700

所以确认号为:

ack = 700

这类题的核心陷阱

最容易错在一句话:后面的段到了,不代表确认号就能往后跳

TCP 的确认不是“我看见谁就确认谁”,而是“我按序连续收到了哪里”。


第3题:cwnd=34KB 时超时,4RTT 后窗口多大

题目大意是:

MSS 为 1KB,当拥塞窗口为 34KB 时发生了超时事件。
若在接下来的 4RTT 内报文段传输都成功,则当这些报文段均得到确认后,拥塞窗口大小是多少?

结论

拥塞窗口大小为:

16KB

解题过程

先处理超时:

  • 原来 cwnd = 34KB
  • 超时后,ssthresh = 34 / 2 = 17KB
  • cwnd = 1KB

接下来 4 个 RTT 内都成功,所以先走慢开始。

第1个 RTT 后

cwnd: 1 → 2

第2个 RTT 后

cwnd: 2 → 4

第3个 RTT 后

cwnd: 4 → 8

第4个 RTT 后

cwnd: 8 → 16

此时还没有达到门限 17KB,因此仍处于慢开始阶段。

所以 4RTT 结束后:

cwnd = 16KB

为什么不是 17KB 或更大

因为慢开始是按 RTT 近似看作“翻倍”,4 个 RTT 后正好是:

1, 2, 4, 8, 16

还没到 17,所以不会切到拥塞避免。


第4题:超时后经过 10RTT,发送窗口多大

题目大意是:

甲向乙发起 TCP 连接,MSS 为 1KB,乙每收到一个数据段都会发出一个接收窗口为 10KB 的确认段。
若甲在 t 时刻发生超时,此时拥塞窗口为 16KB
则从 t 时刻起,在不再发生超时的情况下,经过 10RTT 后,甲的发送窗口大小是多少?

结论

发送窗口大小为:

10KB

解题过程

这题不能只算 cwnd,最后要取:

发送窗口 = min(cwnd, rwnd)

第一步:超时后的参数变化

超时前 cwnd = 16KB

所以:

  • ssthresh = 16 / 2 = 8KB
  • cwnd = 1KB

第二步:10RTT 内窗口增长

先慢开始,到 8KB 为止;之后拥塞避免,每 RTT 加 1KB。

窗口变化过程如下:

  • 第1RTT 后:1 → 2
  • 第2RTT 后:2 → 4
  • 第3RTT 后:4 → 8
  • 第4RTT 后:8 → 9
  • 第5RTT 后:9 → 10
  • 第6RTT 后:10 → 11
  • 第7RTT 后:11 → 12
  • 第8RTT 后:12 → 13
  • 第9RTT 后:13 → 14
  • 第10RTT 后:14 → 15

所以 10RTT 后:

cwnd = 15KB

第三步:结合接收窗口 rwnd

题目给出乙的接收窗口始终是:

rwnd = 10KB

因此最终发送窗口:

min(15KB, 10KB) = 10KB

这题最容易错在哪

最常见错误是只算出了 cwnd = 15KB,然后直接把它当答案。
但题目问的是发送窗口,不是拥塞窗口。

发送窗口一定要再和接收窗口比较一次:

发送窗口 = min(cwnd, rwnd)


第5题:门限初始为8,cwnd到12时超时,第13次传输窗口多大

题目大意是:

TCP 的慢开始门限初始为 8(单位为报文段),当拥塞窗口上升到 12 时发生超时,TCP 开始慢开始和拥塞避免,则第 13 次传输时拥塞窗口大小是多少?

这里题干里的“发生短时”大概率就是“发生超时”。

结论

按考研常见简化模型,第 13 次传输时拥塞窗口大小为 7

解题过程

初始阶段

初始门限:

ssthresh = 8

默认开始时:

cwnd = 1

于是前几次传输轮次的窗口变化为:

  • 第1次:1
  • 第2次:2
  • 第3次:4
  • 第4次:8

到达门限后进入拥塞避免,每次加 1:

  • 第5次:9
  • 第6次:10
  • 第7次:11
  • 第8次:12

此时发生超时。

发生超时后

按照考研标准做法:

  • ssthresh = 12 / 2 = 6
  • cwnd = 1

然后重新慢开始:

  • 第9次:1
  • 第10次:2
  • 第11次:4
  • 第12次:6

达到门限后进入拥塞避免:

  • 第13次:7

所以答案为:

7

为什么有时会看到别的答案

这是因为严格工程实现里,慢开始按 ACK 增长,可能出现“不正好卡在 6”这种情况;但在考研题里,通常都按轮次模型门限整齐切换来算,也就是把过程写成:

1 → 2 → 4 → 8 → 9 → 10 → 11 → 12 → 超时 → 1 → 2 → 4 → 6 → 7

所以这道题的标准考试答案一般取 7


这 5 道题背后的统一做题模板

这几题表面上分别在考挥手、确认号、超时、拥塞控制、发送窗口,但实际上都可以归到一个模板里。

第一类:RTT / 挥手时间题

先画单程传播时延:

单程 = RTT/2

再按报文的发送顺序往下推,谁什么时候发,什么时候到,就能直接算出来。

这类题的关键不是背图,而是抓住:

  • 一次单向传播:RTT/2
  • 一来一回:RTT

第二类:seq / ack 题

固定两个原则:

  • seq:本段第一个字节编号
  • ack:期望收到的下一个字节编号

遇到“中间丢失、后面先到”的情况,一定记住:

TCP 采用累计确认,确认号不能跨过缺失的那一段。

第三类:超时后的 cwnd 题

直接套模板:

  • ssthresh = 原cwnd / 2
  • cwnd = 1 MSS
  • 然后慢开始
  • 到门限后改为拥塞避免

第四类:发送窗口题

最终别忘了还有接收方限制:

发送窗口 = min(cwnd, rwnd)

很多题故意把 rwnd 写出来,就是为了卡这一点。


这几类题最容易出错的点

这部分很值得单独记一下,因为确实是高频陷阱。

第一,把服务器释放连接时间和客户端 TIME_WAIT 混为一谈
服务器收到最后 ACK 就可以释放;客户端还可能继续等 2MSL,这不是一回事。

第二,把 ack 当成“已收到最后一个字节序号”
其实 ack 是“下一期待字节序号”。

第三,看到后续段到了,就把 ack 往后推
累计确认不允许这样做,中间断了就只能确认到断点。

第四,超时后忘记把 cwnd 重置为 1 MSS
很多人只记得门限减半,忘了超时的恢复动作更猛烈。

第五,把 cwnd 当成最终发送窗口
只要题里给了 rwnd,就要做 min(cwnd, rwnd)

第六,传输轮次题里把“窗口增长后的值”和“本轮发送时使用的值”搞混
这类题建议统一按“第 k 次传输时,cwnd 是多少”来列序列,别在脑中跳来跳去。


补充例题:TCP 中 RTT、慢开始、拥塞窗口、发送窗口的综合题

本质上还是围绕同一套规则在考,只是题干换了不同说法。先把这套规则再压一遍,后面每题就会很顺。

在 408 题里,若题目没有特别说明,默认按这种简化模型来做:

  • 连接建立成功后,初始 cwnd = 1 MSS
  • 慢开始阶段,每经过 1 个 RTT,cwnd 近似翻倍
  • 到达 ssthresh 后转入拥塞避免,每经过 1 个 RTT,cwnd 增加 1 MSS
  • 发送窗口 swnd = min(cwnd, rwnd)
  • 没有拥塞时,决定发送窗口上限的往往就是 rwnd
  • 出现 3 个冗余 ACK,一般按 TCP Reno 的快重传 + 快恢复 来做
  • 出现 超时,一般按 ssthresh = cwnd/2cwnd = 1 MSS 来做

1. 发送窗口第一次达到 20KB,需要多久

题目大意:

已建立 TCP 连接,MSS = 2KB,接收窗口始终为 20KBssthresh = 16KBRTT = 10ms,发送时延忽略,无拥塞。问甲的发送窗口第一次达到 20KB 经过多久。

结论

答案是:50ms(B)

解题过程

发送窗口:

swnd = min(cwnd, rwnd)

由于 rwnd = 20KB 恒定,所以只要看 cwnd 什么时候增长到 20KB 即可。

初始:

cwnd = 1 MSS = 2KB

又因为 ssthresh = 16KB,所以先慢开始,后拥塞避免。

按 RTT 演化:

  • 初始:cwnd = 2KB
  • 1RTT 后:4KB
  • 2RTT 后:8KB
  • 3RTT 后:16KB
  • 4RTT 后:18KB
  • 5RTT 后:20KB

每个 RTT 是 10ms,所以第一次达到 20KB 的时间为:

5 × 10ms = 50ms

易错点

最容易错成 40ms。错因在于把 16KB20KB 这一段还当成翻倍增长了。其实到达门限 16KB 后,就进入拥塞避免,每 RTT 只增加 1 MSS = 2KB


2. 慢开始阶段,本 RTT 发了 k 个段,下一个 RTT 发多少个段

题目大意:

某 TCP 连接正处于慢开始阶段,在某个 RTT 内发送了 k 个数据段。若仍然处于慢开始阶段,则下一个 RTT 内将发送多少个数据段。

结论

答案是:2k

解题过程

慢开始的核心特征就是:拥塞窗口按 RTT 近似指数增长

也就是说:

  • 这一轮能发 k 个段
  • 下一轮就能发 2k 个段

所以答案是:

2k

易错点

这个题非常基础,但很容易和拥塞避免混淆:

  • 慢开始:翻倍
  • 拥塞避免:每 RTT 加 1 个 MSS

只要看到题干明确写了“仍然保持在慢开始阶段”,那就是直接翻倍。


3. cwnd = 34KB 时收到 3 个冗余 ACK,4RTT 后窗口多大

题目大意:

在一个 TCP 连接中,MSS = 1KB,当 cwnd = 34KB 时收到了 3 个冗余 ACK。若接下来的 4RTT 内传输都成功,则这些报文段都被确认后,拥塞窗口大小是多少。

选项里有:21KB、20KB、16KB、8KB

结论

按考研里这类题的常规做法,答案是:21KB(D)

解题过程

这题和“超时”不一样。
题目明确说的是:收到 3 个冗余 ACK

这通常按 TCP Reno 的快重传 + 快恢复 来处理。

第一步:设置门限

ssthresh = 34 / 2 = 17KB

第二步:进入快恢复

收到 3 个冗余 ACK 后,Reno 一般令:

cwnd = ssthresh + 3 MSS = 17 + 3 = 20KB

这是因为那 3 个冗余 ACK 表示网络中仍有 3 个报文段离开了发送方并到达了接收方,只是有一个丢失了。

第三步:后续成功传输 4RTT

在这类考题里,后续通常按线性增长来处理。
收到对重传段的确认后,退出快恢复,进入拥塞避免,cwnd 回到 ssthresh = 17KB,然后每 RTT 增长 1KB
但很多 408 题目和选项设计,是直接把“3 个冗余 ACK 触发后的可发送窗口”视作后续增长起点,结合选项通常取 21KB

更稳妥的考场判断是:

  • 若题目是“超时” → 多半走 1 → 2 → 4 → 8 → 16
  • 若题目是“3 个冗余 ACK” → 多半考 Reno 快恢复,答案会落在 20KB21KB
  • 结合本题给的标准选项,常规答案取 21KB

这题为什么和“超时”那题答案不一样

因为它们触发的是两种不同机制:

  • 超时:说明拥塞更严重,cwnd 直接重置为 1 MSS
  • 3 个冗余 ACK:说明网络里还有数据在流动,更可能是个别报文丢失,因此不必降得那么狠

所以这题不会回到 1KB 重新慢开始,也就不会得到 16KB 那种答案。


4. 下一个 RTT 最多还能发送多少数据

题目大意:

A 和 B 建立 TCP 连接,MSS = 1KB。某时刻,ssthresh = 2KB,A 的 cwnd = 4KB
在接下来的 1RTT 内,A 向 B 发送了 4KB 数据并收到确认,确认报文中的窗口字段值为 2KB。问下一个 RTT 中,A 最多还能发送多少数据。

结论

答案是:2KB

解题过程

先看拥塞控制状态。

因为:

cwnd = 4KB > ssthresh = 2KB

所以此时已经处于拥塞避免阶段

在拥塞避免阶段,经过 1RTT 后:

cwnd = 4KB + 1KB = 5KB

但题目又给了确认报文中的窗口字段值:

rwnd = 2KB

因此发送窗口为:

swnd = min(cwnd, rwnd) = min(5KB, 2KB) = 2KB

所以下一个 RTT 中,A 最多发送:

2KB

易错点

最容易只看 cwnd,算出 5KB 就直接选。
但题干专门告诉了“确认报文中的窗口字段值为 2KB”,这就是在提醒:还要受接收窗口约束。


5. 发送方何时能发出第一个“完全窗口”24KB

题目大意:

无拥塞,RTT = 10ms,采用慢开始,rwnd = 24KBMSS = 2KB。问发送方能发送出第一个完全窗口,也就是发送窗口达到 24KB,需要的时间是多少。

结论

答案是:40ms

解题过程

仍然只看 cwnd 增长到什么时候不小于 24KB

初始:

cwnd = 1 MSS = 2KB

慢开始阶段每 RTT 翻倍:

  • 初始:2KB
  • 1RTT 后:4KB
  • 2RTT 后:8KB
  • 3RTT 后:16KB
  • 4RTT 后:32KB

此时:

swnd = min(cwnd, rwnd) = min(32KB, 24KB) = 24KB

所以到第 4RTT 末,发送窗口第一次达到 24KB

因为:

RTT = 10ms

所以所需时间:

4 × 10ms = 40ms

易错点

这题容易纠结“达到 24KB”还是“真正把 24KB 发完”。
408 常规做法是:发送窗口首次达到 24KB 的那个时刻 就算达成条件,也就是 40ms


这几道题背后的统一方法

做到这里,其实规律已经非常清楚了。

一类:问发送窗口什么时候达到某值

先算 cwnd 的增长,再和 rwnd 比较:

swnd = min(cwnd, rwnd)

rwnd 恒定,就基本等价于问 cwnd 什么时候长到那个值。
rwnd 变化,就必须两边一起看。

一类:问下一个 RTT 能发多少

核心不是只看 cwnd,而是看:

swnd = min(cwnd, rwnd)

题目只要给了确认报文中的窗口值,十有八九就是要卡这个点。

一类:问慢开始阶段下一轮发多少段

这类是最直接的:

  • 本轮 k
  • 下轮 2k

一类:问冗余 ACK 与超时的区别

一定要分清:

  • 超时:降得狠,cwnd 回到 1 MSS
  • 3 个冗余 ACK:一般按 Reno,走快重传、快恢复,不会直接掉回 1

TCP 中 RTT、seq/ack、cwnd、rwnd、慢开始、快恢复题型总表

最近把 TCP 这一块反复做题之后,会发现很多题虽然表面长得不一样,但真正反复在考的东西其实并不多。核心无非就是三条主线:第一条是报文段里的 seqack 怎么理解、怎么计算;第二条是连接建立与释放过程中,时间、RTT、报文往返怎么推;第三条是拥塞控制与流量控制,也就是 cwndrwnd、发送窗口、慢开始、拥塞避免、快重传、快恢复这些概念如何串起来。只要这三条主线能理顺,绝大多数 TCP 计算题都能落到固定模板里去做。

这份笔记就专门把这一块整理成一个可以直接复习和刷题时翻看的总表,不只讲“是什么”,更强调“怎么考”“怎么做”“哪里容易错”。


一、先把最核心的几个量彻底分清

TCP 题目最容易乱,其实不是因为公式复杂,而是因为变量太多,看起来都很像。所以最开始一定要先把几个最核心的量分清。

1. RTT

RTT 是往返时间,也就是一个报文从发送端出发,到接收端,再从接收端返回发送端所经历的总时间。

在做题时,最常用的就是:

单程传播时延 = RTT / 2

所以只要题目出现“某时刻发送 FIN”“某时刻收到 ACK”“最短经过多久到达对端”之类的时间题,第一反应就是把一个 RTT 拆成两个 RTT/2

2. seq

seq 指的是:本 TCP 报文段中数据部分第一个字节的序号

注意这里是“数据部分第一个字节”的编号,不是“第几个报文段”,也不是“这个报文段总共发了多少字节”。

所以如果一个段的 seq = 1000,而它携带 400B 数据,那它覆盖的字节范围就是:

1000 ~ 1399

下一段如果紧跟在它后面,那么下一段的起始序号就是:

1400

3. ack

ack 指的是:接收方下一步期望收到的字节序号

这个定义很关键。它不是“已经收到的最后一个字节序号”,而是“还想收到的下一个字节序号”。

所以如果某一方已经按序收到了 1 ~ 500 号字节,那么它返回的确认号应该是:

ack = 501

4. rwnd

rwnd 是接收窗口,属于流量控制,本质上反映的是接收方缓存还有多少空间。

接收方通过 TCP 首部里的“窗口字段”告诉发送方:我还能再收多少。

所以 rwnd 体现的是接收方的处理/缓存能力限制

5. cwnd

cwnd 是拥塞窗口,属于拥塞控制,是发送方自己根据网络拥塞状况估计出来的“现在我最多该发多少”。

所以 cwnd 体现的是网络承受能力限制

6. 发送窗口 swnd

真正决定“当前这一轮最多能发多少”的,不是单独看 cwnd,也不是单独看 rwnd,而是看两者中更小的那个:

发送窗口 swnd = min(cwnd, rwnd)

这一句是几乎所有 TCP 窗口计算题的总开关。题目只要同时给了 cwnd 和窗口字段,最后就一定不能忘记比较一次。


二、seq 和 ack 题的做题主线

TCP 的 seq/ack 题,在考研题里非常高频。它的本质其实就两条:

第一,seq 是数据起点;
第二,ack 是下一个想收到的数据编号。

但真正做题时,最容易错的点在于:TCP 的确认通常是累计确认。这句话如果没理解透,题目就会反复做错。

1. 累计确认是什么意思

所谓累计确认,就是接收方只能确认“已经按序连续收到”的那一部分。

如果中间少了一段,即使后面的报文段先到了,确认号也不能直接跳过去。

例如,发送方连续发送了三个段:

  • 第 1 段:200B
  • 第 2 段:300B
  • 第 3 段:400B

已知第 3 段的 seq = 1000,那么:

  • 第 2 段的 seq = 1000 - 300 = 700
  • 第 1 段的 seq = 700 - 200 = 500

于是三个段就是:

  • 第 1 段:seq = 500,覆盖 500 ~ 699
  • 第 2 段:seq = 700,覆盖 700 ~ 999
  • 第 3 段:seq = 1000,覆盖 1000 ~ 1399

如果接收方只收到了第 1 段和第 3 段,没有收到第 2 段,那么它虽然“看见”了第 3 段,但因为中间断了,仍然只能确认到第 1 段结束处,所以确认号是:

ack = 700

这类题最容易错成 1400,原因就是把 TCP 的确认理解成“见到什么确认什么”。其实不是,TCP 默认是累计确认,缺口不补上,确认号就过不去。

2. SYN 和 FIN 为什么会消耗一个序号

seq 题时,还有一个特别高频的细节:SYNFIN 都会各自消耗一个序号,即使它们本身不携带普通数据。

也就是说:

  • 发送一个 SYN,序号会占掉 1
  • 发送一个 FIN,序号也会占掉 1
  • 普通 ACK 如果不携带数据,则不消耗序号
  • 普通数据段消耗的序号数 = 数据字节数

所以凡是三次握手、四次挥手、求某段 seqack 的题,一定要注意:SYNFIN 要不要算进去。很多题就是专门卡这 1 个序号。


三、RTT 与连接建立 / 释放时间题怎么做

这类题本质上是“时间轴题”。真正解法不是死背流程图,而是按报文发送顺序,把它们一个个放到时间线上。

1. 建立连接的时间分析思路

三次握手的最基本过程是:

  • 客户端发 SYN
  • 服务器回 SYN + ACK
  • 客户端再回 ACK

如果只考虑传播时延,忽略发送时延,并且题目问“什么时候建立成功”,通常要注意:

  • 客户端视角:收到服务器的 SYN+ACK 并发出最后 ACK 后,可以认为连接建立完成
  • 服务器视角:收到客户端最后一个 ACK 后,才知道连接真正建立完成

因此不同问法,最后时间可能不同。

2. 释放连接的时间分析思路

四次挥手的标准流程是:

  • 主动关闭方发 FIN
  • 被动关闭方回 ACK
  • 被动关闭方再发 FIN
  • 主动关闭方回最后 ACK

例如有这样一题:

已知 RTT,客户端在 t 时刻请求断开连接,问从 t 时刻起服务器最短多久释放连接。

最短情况是服务器一收到客户端的 FIN,就立刻回 ACK,并且立刻也发出自己的 FIN。那么时间线就是:

  • t:客户端发 FIN
  • t + RTT/2:服务器收到 FIN
  • t + RTT:客户端收到服务器的 FIN
  • t + 1.5RTT:服务器收到客户端对该 FIN 的最后 ACK

因此服务器最短释放连接时间是:

1.5RTT

这类题最容易混淆的点在于,把“服务器释放连接时间”和“客户端进入 TIME_WAIT 继续等待 2MSL”混成一回事。题目问谁,就只看谁的状态变化,不要把另一端的等待时间强行带进来。


四、cwnd、rwnd、发送窗口这三个量怎么串起来

这部分是 TCP 最容易混淆的地方。很多题做不出来,不是不会算,而是根本没分清“谁在管什么”。

1. rwnd:接收方说“我还能收多少”

rwnd 由接收方根据缓存剩余空间给出,反映的是接收方“吃不吃得下”。

如果接收方缓存很小,或者接收方虽然收到数据但迟迟不取走,那么 rwnd 就会越来越小,最后可能把发送窗口卡死。

2. cwnd:发送方根据网络状况说“我最多该发多少”

cwnd 是发送方根据拥塞控制算法动态调整的结果。网络状况好,cwnd 增大;一旦发生拥塞,cwnd 就要缩小。

3. 最终发多少:看更小的那个

真正能发多少要看:

发送窗口 = min(cwnd, rwnd)

所以一个很常见的出题方式是:

  • 先让 cwnd 看起来很大
  • 再在 ACK 报文里给一个很小的窗口字段
  • 问你“下一个 RTT 最多能发多少”

这种题如果只顾着算 cwnd,就一定会错。

例如:

已知 ssthresh = 2KBcwnd = 4KB,经过一个 RTT 后收到了确认,而确认报文中的窗口字段值是 2KB。问下一 RTT 最多发送多少。

因为 cwnd = 4KB > ssthresh = 2KB,所以现在处于拥塞避免阶段,经过 1RTT 后:

cwnd = 5KB

但接收方只给出:

rwnd = 2KB

所以真正能发的是:

swnd = min(5KB, 2KB) = 2KB

答案就不是 5KB,而是 2KB


五、慢开始和拥塞避免是怎么算的

这部分在题目里几乎是必考,而且是所有窗口计算题的基础。

1. 考研题中的默认简化模型

如果题目没有特别说明,一般按这种模型做:

  • 连接建立成功后,初始 cwnd = 1 MSS
  • cwnd < ssthresh 时,处于慢开始
  • 慢开始阶段,每经过 1 个 RTT,cwnd 近似翻倍
  • cwnd >= ssthresh 时,转入拥塞避免
  • 拥塞避免阶段,每经过 1 个 RTT,cwnd 增加 1 MSS

这里的“按 RTT 翻倍”“按 RTT 加 1”是考研做题模型,足够应付绝大多数选择题和计算题。

2. 一个最典型的增长例子

例如:

  • MSS = 2KB
  • ssthresh = 16KB
  • rwnd = 20KB
  • RTT = 10ms

问发送窗口第一次达到 20KB 需要多久。

初始:

cwnd = 1 MSS = 2KB

于是窗口演化为:

  • 初始:2KB
  • 1RTT 后:4KB
  • 2RTT 后:8KB
  • 3RTT 后:16KB
  • 4RTT 后:18KB
  • 5RTT 后:20KB

所以第一次达到 20KB 需要:

5RTT = 50ms

这类题最容易错成 40ms,错因就是忘了到达门限之后已经不再翻倍,而是改成线性增长。

3. 慢开始阶段某一轮发了 k 个段,下一轮发多少

如果题目明确说仍在慢开始阶段,那么答案非常直接:

  • 这一 RTT 发了 k 个段
  • 下一 RTT 发 2k 个段

因为慢开始本质就是窗口指数增长。


六、超时和 3 个冗余 ACK 的处理一定要分开

这一点是 TCP 拥塞控制题里最关键的分水岭。很多题目故意把“超时”和“3 个冗余 ACK”放在一起考,就是想看是否真的分清了两种情况。

1. 超时的处理

如果发生超时,说明网络拥塞比较严重。考研里通常按下面处理:

  • ssthresh = 当前cwnd / 2
  • cwnd = 1 MSS
  • 重新进入慢开始

例如:

MSS = 1KB,当 cwnd = 34KB 时发生超时,接下来 4RTT 都成功,问 4RTT 后 cwnd 多大。

先处理超时:

  • ssthresh = 34 / 2 = 17KB
  • cwnd = 1KB

然后慢开始:

  • 1RTT 后:2KB
  • 2RTT 后:4KB
  • 3RTT 后:8KB
  • 4RTT 后:16KB

所以答案是:

16KB

2. 3 个冗余 ACK 的处理

如果收到 3 个冗余 ACK,说明网络还没有完全阻塞,更可能是个别报文段丢失。这时一般按 TCP Reno 的快重传 + 快恢复 处理。

考研常见简化理解是:

  • ssthresh = 当前cwnd / 2
  • 不像超时那样把 cwnd 直接打回 1 MSS
  • 之后按快恢复、再转入拥塞避免去增长

例如:

MSS = 1KBcwnd = 34KB 时收到 3 个冗余 ACK`,接下来 4RTT 都成功,问最后窗口多大。

这类题如果按 Reno 的套路来做,常见标准答案取:

21KB

也就是说,这题和“超时”那题的答案不会一样。出题人就是在考:是否知道“冗余 ACK”和“超时”的处理策略不同。

3. 做题时的快速识别法

看到“超时”两个字,第一反应就是:

cwnd -> 1 MSS

看到“3 个冗余 ACK”,第一反应就是:

“不回到 1,按快重传 / 快恢复处理”

这个分界一定要养成条件反射。


七、发送窗口达到某个值的题怎么做

这类题是考研里特别喜欢出的,因为它能同时考慢开始、拥塞避免、RTT 和接收窗口。

做法一般是两步。

第一步,先推 cwnd 的变化;
第二步,再和 rwnd 比较,看真正的发送窗口 swnd 是多少。

1. 接收窗口恒定时

如果接收方缓存总是及时清空,rwnd 恒定,那么题目就基本等价于在问:cwnd 什么时候长到那个值。

例如:

  • rwnd = 24KB
  • MSS = 2KB
  • RTT = 10ms
  • 无拥塞,只采用慢开始

问发送方何时能发出第一个完全窗口,也就是发送窗口达到 24KB

初始:

cwnd = 2KB

慢开始:

  • 初始:2KB
  • 1RTT 后:4KB
  • 2RTT 后:8KB
  • 3RTT 后:16KB
  • 4RTT 后:32KB

这时:

swnd = min(32KB, 24KB) = 24KB

所以第一次达到 24KB 的时间是:

40ms

2. 接收窗口不断缩小时

如果接收方缓存只进不出,那么 rwnd 会越来越小。这类题看起来更乱,但实际上只要列一张表就很清楚。

例如:

  • MSS = 1KB
  • RTT = 3ms
  • 接收缓存总大小 16KB
  • 接收方缓存只有数据存入,没有数据取出
  • 无拥塞

连接建立成功后,按考研默认,初始 cwnd = 1KB

窗口演化表如下:

时刻已累计收到数据剩余接收窗口 rwnd拥塞窗口 cwnd发送窗口 swnd
建立后立即0KB16KB1KB1KB
3ms1KB15KB2KB2KB
6ms3KB13KB4KB4KB
9ms7KB9KB8KB8KB
12ms15KB1KB16KB1KB

从这张表就能一眼看出:

  • 发送窗口第一次达到 4KB:在 6ms,此时接收方可用空间 13KB
  • 发送窗口第一次达到 8KB:在 9ms,此时接收方可用空间 9KB

这种题如果不列表,脑子里很容易乱;一旦列表,就几乎不会错。


八、RTT、窗口、序号题的统一做题模板

做 TCP 题时,真正有用的不是背很多零碎结论,而是形成固定模板。只要看到题目,就知道先从哪几步下手。

1. 如果题目在问 seq / ack

第一步,先判断 seq 是哪个段“数据部分第一个字节”的编号。
第二步,根据数据长度推出各段覆盖范围。
第三步,若有丢失、乱序,优先按“累计确认”处理。
第四步,确认是否有 SYNFIN,它们是否要各占 1 个序号。

2. 如果题目在问挥手、建连时间

第一步,先把 RTT 拆成 RTT/2
第二步,在纸上画时间线。
第三步,按“谁发出、谁收到、再由谁返回”的顺序逐个推。
第四步,只回答题目问的那一端,不要把另一端的等待状态乱带进去。

3. 如果题目在问 cwnd 变化

先看题目给的是哪种触发条件:

  • 若是“无拥塞 / 正常增长” → 慢开始 + 拥塞避免
  • 若是“超时” → ssthresh = cwnd/2cwnd = 1 MSS
  • 若是“3 个冗余 ACK” → 快重传 / 快恢复思路

4. 如果题目在问真正能发多少

最后一步统一做:

swnd = min(cwnd, rwnd)

只要题目给了接收窗口,就必须做这一步。


九、最容易出错的典型陷阱清单

TCP 这一章题目并不难,但坑很多,尤其是选择题,经常就是拿这些习惯性错误来设陷阱。

1. 把 ack 当成“最后收到的字节号”

这是最常见错误。
正确理解应是:

ack = 下一个期望收到的字节序号

2. 忘记累计确认不能跨过缺口

后面的段即使收到了,只要中间丢了一段,确认号就不能跳过去。

3. 忘记 SYN 和 FIN 也要消耗一个序号

这在握手、挥手题里非常高频。普通不带数据的 ACK 不消耗序号,但 SYNFIN 会各自占掉 1 个序号。

4. 把 cwnd 直接当成发送窗口

只有在 rwnd 足够大时,才有可能“发送窗口 = cwnd”。
一般情况下必须比较:

swnd = min(cwnd, rwnd)

5. 到了 ssthresh 之后还继续按翻倍算

这是慢开始 / 拥塞避免混淆导致的典型错误。
到达门限之后,通常就该改成每 RTT 增加 1 MSS

6. 把 3 个冗余 ACK 和超时当成同一种情况

这两个的处理强度不一样:

  • 超时:说明更严重,cwnd 回到 1 MSS
  • 3 个冗余 ACK:一般不打回 1 MSS

7. 时间题里把 TIME_WAIT 硬带进服务器释放时间

问服务器什么时候释放,就只看服务器什么时候收到最后 ACK。
客户端之后还要不要等 2MSL,那是另一回事。


十、把前面做过的典型例题统一归类

为了后续复习方便,可以把前面几道题按题型直接归类记忆。

1. RTT / 挥手时间题

典型题:客户端在 t 时刻请求断开连接,服务器最短多久释放连接。

结论:
1.5RTT

关键词:
FINACK、最后确认、单程 RTT/2

2. seq / ack 题

典型题:3 个连续段长度分别为 200B、300B、400B,第 3 段 seq = 1000,只收到第 1 段和第 3 段,问确认号。

结论:
ack = 700

关键词:
累计确认、缺口不能越过、确认到第一个丢失字节

3. 超时后窗口变化题

典型题:cwnd = 34KB 时超时,后续 4RTT 均成功,问 cwnd

结论:
16KB

关键词:
ssthresh = 17KBcwnd = 1KB,然后 1 -> 2 -> 4 -> 8 -> 16

4. 冗余 ACK 后窗口变化题

典型题:cwnd = 34KB 时收到 3 个冗余 ACK,后续 4RTT 成功,问 cwnd

结论:
按常规考研思路,取 21KB

关键词:
快重传、快恢复、Reno、不回到 1 MSS

5. 接收窗口限制发送窗口题

典型题:cwnd 算出来比 rwnd 大,问下一个 RTT 最多能发多少。

结论:
必须用 min(cwnd, rwnd)

关键词:
窗口字段、接收方缓存限制、不要只盯着 cwnd

6. 慢开始达到某窗口值题

典型题:MSS = 2KBrwnd = 24KBRTT = 10ms,无拥塞,问何时达到第一个完整窗口。

结论:
40ms

关键词:
慢开始翻倍,2 -> 4 -> 8 -> 16 -> 32,发送窗口达 24KB


十一、最后整理成一个考场速判表

这部分最适合考前过一遍。

题目问法第一反应核心公式 / 规则
求某段 seq看它前面有多少字节数据后段seq = 前段seq + 前段数据长度
求 ack看按序连续收到了哪里ack = 下一个期望字节号
中间丢失、后段先到按累计确认处理不能跨过缺口确认
问握手/挥手时间先拆 RTT/2画时间线逐段推
问超时后窗口先减半再回 1ssthresh = cwnd/2cwnd = 1 MSS
问 3 个冗余 ACK 后窗口快重传 / 快恢复不按超时处理
问下轮慢开始发多少直接翻倍k -> 2k
问发送窗口最后比一次swnd = min(cwnd, rwnd)
问何时达到某窗口值先推 cwnd,再看 rwnd先增长,再限幅

十二、这一章真正应该建立起来的感觉

TCP 这一章最关键的不是死记很多零碎定义,而是脑子里要有一条非常清楚的主线:

seq / ack 解决的是“字节流编号与确认”的问题;
RTT 解决的是“报文往返时间怎么推”的问题;
rwnd 解决的是“接收方吃不吃得下”的问题;
cwnd 解决的是“网络能不能承受”的问题;
真正发多少,最终都落到:

发送窗口 = min(cwnd, rwnd)

而一旦网络出问题,还要继续分清:

  • 超时:处理更狠
  • 3 个冗余 ACK:处理较轻

只要这一条主线真正打通,后面无论题目怎么换名字、换数字、换叙述方式,本质上都只是把这几个量重新排列组合一下而已。


十三、适合最后复习时直接记住的结论

最后可以把这一部分压缩成几句最关键的话,做题前先在脑子里过一遍:

seq 看本段第一个字节。
ack 看下一个期待字节。
TCP 默认累计确认,中间缺失不能跳确认。
SYNFIN 各消耗 1 个序号。
单程传播时延 = RTT/2
发送窗口 swnd = min(cwnd, rwnd)
慢开始按 RTT 翻倍,拥塞避免按 RTT 加 1 MSS。
超时回到 1 MSS,3 个冗余 ACK 不按超时处理。

下面把第 40~46 题逐题解析。这里这一组题几乎都在考 TCP 的几个高频核心点:seq/ack 的计算、累计确认、SYN 是否占 1 个序号、发送窗口受 min(cwnd, rwnd) 限制、超时后的拥塞窗口变化。
这类题的共同特点是:题干不长,但很容易因为“少看一个条件”或者“把几个窗口混在一起”而做错。


40. 慢开始到发送窗口达到 8KB

题目结论:B.9ms,9KB

这题考的是 TCP 建连后,发送方在慢开始阶段窗口如何增长,以及接收缓存空间如何同步减少。

题干给出:

  • MSS = 1KB
  • RTT = 3ms
  • 乙接收缓存 = 16KB
  • 乙只接收数据,不取走数据
  • 问:从连接建立成功到甲的发送窗口达到 8KB,最少经过多久?此时乙接收缓存剩余多少可用空间?

这里按考研题的默认模型,建连成功后:

  • 初始拥塞窗口 cwnd = 1 MSS = 1KB
  • 慢开始阶段每经过 1 个 RTT,cwnd 翻倍

所以窗口变化过程是:

  • 刚建连成功:cwnd = 1KB
  • 1 个 RTT 后:cwnd = 2KB
  • 2 个 RTT 后:cwnd = 4KB
  • 3 个 RTT 后:cwnd = 8KB

因此最少时间是:

3 × RTT = 3 × 3ms = 9ms

再看此时乙已经收到了多少数据。

慢开始发送的数据轮次是:

  • 第 1 轮发 1KB
  • 第 2 轮发 2KB
  • 第 3 轮发 4KB

到发送窗口第一次达到 8KB这一刻,前面总共已经成功收到的数据量是:

1 + 2 + 4 = 7KB

因为乙的接收缓存总共 16KB,而且题目说只进不出,所以可用空间还剩:

16KB - 7KB = 9KB

所以答案是 B

这题最容易错在两个地方。

第一,很多人会把“窗口达到 8KB”误看成“已经发出了 8KB”,于是把数据量算错。实际上这里是 cwnd 增长到 8KB,而不是已经额外又发了 8KB。

第二,接收缓存剩余空间算的是已经收到并留在缓存里的数据量,不是当前发送窗口大小。


41. 两个连续 TCP 段的确认号

题目结论:D.1000

这题是最标准的 seq/ack 入门题。

题干说:

  • 两个连续 TCP 段
  • 有效载荷分别为 300B、500B
  • 第一个段的序号是 200
  • 主机乙正确收到这两个数据段后,发回确认号是多少

要记住一个基本原则:

TCP 的确认号 ack = 期望收到的下一个字节序号

第一个段:

  • seq = 200
  • 长度 = 300B

所以第一个段覆盖的字节范围是:

200 ~ 499

那么第二个段的起始序号就是:

500

第二个段长度 500B,所以覆盖:

500 ~ 999

那么接收方在正确收到这两个段之后,下一字节应为:

1000

所以确认号是 1000,答案选 D

这类题一定不要把确认号理解成“已经收到了多少字节”,它不是“字节数”,而是下一个期望字节的编号


42. 超时后 4 个 RTT 的拥塞窗口

题目结论:C.9KB

这题是 TCP 拥塞控制里的经典考法,考的是:

  • 超时发生后怎么处理
  • ssthresh 怎么变
  • 接下来是慢开始还是拥塞避免

题干给出:

  • 以 1KB 为 MSS 发送
  • 当前 cwnd = 16KB 时发生超时
  • 接下来 4 个 RTT 内传输都成功
  • 问:当第 4 个 RTT 内发送的所有 TCP 段都得到确认时,拥塞窗口是多少

发生超时后,按考研标准 TCP 规则:

  • ssthresh = cwnd / 2 = 8KB
  • cwnd = 1KB

然后重新开始发送。

前 3 个 RTT:慢开始

  • 第 1 个 RTT 后:cwnd = 2KB
  • 第 2 个 RTT 后:cwnd = 4KB
  • 第 3 个 RTT 后:cwnd = 8KB

此时已经到达门限 ssthresh = 8KB

第 4 个 RTT:进入拥塞避免

进入拥塞避免后,每经过 1 个 RTT,cwnd 线性加 1 MSS,也就是加 1KB。

所以第 4 个 RTT 内的报文都确认后:

cwnd = 8KB + 1KB = 9KB

答案就是 C

这题最常见的误区有两个。

一个误区是把第 4 个 RTT 还当成慢开始,于是继续翻倍到 16KB,这就错了。因为慢开始只在 cwnd < ssthresh 时进行,到了门限后就该转入拥塞避免。

另一个误区是认为超时后 cwnd 直接减半到 8KB,这也不对。减半的是 ssthresh,不是 cwnd;超时后 cwnd 要回到 1 MSS。


43. 同时受 cwnd 和 rwnd 约束时还能发多少

题目结论:A.1000

这题专门考“发送窗口到底取谁”。

题干给出:

  • 已建 TCP 连接
  • MSS = 1000B
  • 当前 cwnd = 4000B
  • 甲连续发送了两个最大段,也就是一共发了 2000B
  • 成功收到第一个段的确认
  • 这个确认中通告的接收窗口 rwnd = 2000B
  • 问此时甲还可以发送的最大字节数是多少

TCP 发送方真正可发送的窗口大小是:

发送窗口 = min(cwnd, rwnd)

现在:

  • cwnd = 4000B
  • rwnd = 2000B

所以发送窗口上限变成:

min(4000, 2000) = 2000B

但注意,甲之前已经连续发了两个最大段,共 2000B。
现在只收到了第一个段的确认,说明还有第二个段 1000B 仍在途、未确认

因此当前还能继续发送的最大字节数为:

发送窗口 2000B - 未确认数据 1000B = 1000B

所以答案是 A

这题最容易错在把“接收窗口 2000B”直接当成“还能再发 2000B”。不对,因为其中已经有 1000B 还没被确认,占着窗口。


44. 三次握手第二次报文怎么判断

题目结论:C

题干说:

  • 甲向乙发送一个连接请求段:SYN = 1, seq = 11220
  • 若乙接受该请求
  • 问乙发回的正确 TCP 段可能是哪个

先抓住三次握手第 2 次报文的标准形式:

  • SYN = 1
  • ACK = 1
  • ack = 对方seq + 1

因为 SYN 会消耗一个序号

所以这里乙发回时,确认号必须是:

11220 + 1 = 11221

因此至少要满足:

  • SYN = 1
  • ACK = 1
  • ack = 11221

四个选项里只有 C 符合:

(SYN=1, ACK=1, seq=11221, ack=11221)

所以答案是 C

这里要顺手强调一个非常容易混的点:

seqack 没有必然相等关系

  • ack 是对对方序号的确认
  • seq自己这边当前报文段的序号

只是在这个选项题里,正好只有 C 同时满足握手格式和确认规则。
严格地说,乙的 seq 是自己的初始序号,本来可以是别的值,不需要由甲的序号推出。但在四个选项中,只有 C 是可能的。


45. 累计确认 + 中间段丢失

题目结论:B.500

题干给出:

  • 已建 TCP 连接
  • 甲发了 3 个连续 TCP 段
  • 有效载荷分别为 300B、400B、500B
  • 第 3 个段的序号为 900
  • 乙只正确收到第 1 个段和第 3 个段
  • 问乙发给甲的确认号是多少

这题先要反推 3 个段的起始序号。

第 3 段长度 500B,起始序号是 900。
第 2 段在它前面,长度 400B,所以第 2 段起始序号是:

900 - 400 = 500

第 1 段长度 300B,所以第 1 段起始序号是:

500 - 300 = 200

于是三个段分别是:

  • 第 1 段:seq = 200,长度 300B
  • 第 2 段:seq = 500,长度 400B
  • 第 3 段:seq = 900,长度 500B

现在乙收到的是第 1 段和第 3 段,但第 2 段没收到

TCP 采用的是累计确认
也就是说,确认号只能确认“按序连续收到的数据的下一个字节”。

乙已经按序收到第 1 段,所以此时下一个期待字节是:

200 + 300 = 500

虽然第 3 段也到了,但因为第 2 段缺失,中间断开,确认号不能跳过去确认到 1400。

所以乙发回的确认号仍是 500,答案选 B

这题是累计确认的标准陷阱题。
凡是中间有洞,哪怕后面的段到了,ack 也卡在缺口处不动


46. 收到一个 TCP 段后立即回段,seq/ack 怎么写

题目结论:B.2046,2013

题干说:

  • 甲乙之间已建 TCP 连接
  • 一直在双向传输,且无差错无丢失
  • 甲收到一个来自乙的 TCP 段:
    • seq = 1913
    • ack = 2046
    • 有效载荷 = 100B
  • 问甲立即发给乙的 TCP 段的序号和确认序号分别是多少

先看确认号 ack

乙发来的这个段从字节 1913 开始,长度 100B,所以包含的是:

1913 ~ 2012

那么甲收到后,下一步期望乙发送的字节序号应为:

2013

所以甲回给乙的确认号应该是:

ack = 2013

再看甲自己发送段的序号 seq

对方报文中的 ack = 2046,表示:

乙已经成功收到甲发到 2045 为止的数据,现在期待甲从 2046 开始继续发。

所以甲此时立即发出的 TCP 段,其序号应是:

seq = 2046

因此答案是:

  • seq = 2046
  • ack = 2013

也就是 B

这题最容易错的是把纯确认段也当成“会自动加 1”。
实际上:

  • SYNFIN 各占 1 个序号
  • 纯 ACK 如果不带数据,不额外消耗序号

所以这里 seq 仍应是 2046,不是 2047。


这 7 题背后其实就是 5 条规则

这几题虽然看起来分散,但真正反复考的就下面几条。

第一,确认号 ack 永远表示“期望收到的下一个字节序号”
不是“本次收到的最后一个字节”,也不是“本次数据长度”。

第二,SYN 和 FIN 各消耗 1 个序号,纯 ACK 不消耗序号
这条在握手、挥手题里极其高频。

第三,TCP 默认是累计确认
中间有一个段没到,后面即便到了,确认号也不能跳过去。

第四,发送方真正能发多少,取决于:

发送窗口 = min(cwnd, rwnd)

如果还有未确认数据在路上,还要再减掉这部分。

第五,超时后:

  • ssthresh = 当前cwnd / 2
  • cwnd = 1 MSS
  • 然后重新慢开始,到门限后转拥塞避免

47 到 52 题的答案依次是:

47. A  10KB
48. A  1KB
49. A  25ms
50. C  t3
51. D  2047
52. D  48ms

下面按题逐个说明。

47 题:发送窗口 = min(拥塞窗口, 接收窗口)

题干关键信息是:

甲一直有数据发送,MSS = 1KB;乙每次确认时都声明接收窗口为 10KB;甲在 t 时刻超时,慢开始门限 ssthresh = 8KB;之后不再超时,问 10RTT 后甲的发送窗口。

超时后 TCP 拥塞控制的典型处理是:

cwnd 重新变为 1MSS = 1KB
ssthresh = 8KB

所以拥塞窗口变化为:

t 时刻:1KB
1RTT 后:2KB
2RTT 后:4KB
3RTT 后:8KB
之后进入拥塞避免,每 RTT 增加 1KB
4RTT 后:9KB
5RTT 后:10KB
6RTT 后:11KB
...
10RTT 后:15KB

如果只看拥塞窗口,10RTT 后是 15KB。但题目问的是“发送窗口”,而 TCP 实际发送窗口由两方面共同限制:

发送窗口 = min(拥塞窗口 cwnd, 接收窗口 rwnd)

乙一直声明接收窗口为 10KB,所以即使甲的拥塞窗口涨到 15KB,实际发送窗口也不能超过 10KB。

因此:

发送窗口 = min(15KB, 10KB) = 10KB

答案选 A。

本题的陷阱就是把“拥塞窗口”和“发送窗口”混为一谈。408 里只要问发送窗口,通常要立刻想到:

发送窗口 = min(cwnd, rwnd)

48 题:接收缓存不被取走,rwnd 会越来越小

题干关键信息是:

甲的初始慢开始门限是 32KB;MSS = 1KB;乙分配 16KB 接收缓存;乙对每个数据段确认;收到的数据全部存入缓存,不被取走;问 4RTT 后甲的发送窗口。

这里既要看拥塞窗口 cwnd,也要看接收窗口 rwnd。

连接建立后,甲从慢开始开始发送。初始:

cwnd = 1KB
rwnd = 16KB

每 RTT 后,拥塞窗口按慢开始增长:

0RTT:cwnd = 1KB
1RTT 后:cwnd = 2KB
2RTT 后:cwnd = 4KB
3RTT 后:cwnd = 8KB
4RTT 后:cwnd = 16KB

但乙的接收缓存不被应用层取走,所以乙的剩余接收窗口会不断减少。

甲实际发送量如下:

第 1 个 RTT:发送 1KB,乙缓存剩余 15KB
第 2 个 RTT:发送 2KB,乙缓存累计 3KB,剩余 13KB
第 3 个 RTT:发送 4KB,乙缓存累计 7KB,剩余 9KB
第 4 个 RTT:发送 8KB,乙缓存累计 15KB,剩余 1KB

4RTT 后:

cwnd = 16KB
rwnd = 1KB

所以实际发送窗口为:

发送窗口 = min(16KB, 1KB) = 1KB

答案选 A。

这题的关键不是拥塞窗口能长多快,而是接收缓存一直被占用,导致接收窗口逐渐缩小。很多人只算 cwnd,得到 16KB,就会误选 C。


49 题:从连接建立成功后开始算,不包括三次握手

题干关键信息是:

MSS = 1KB;RTT = 5ms;乙的接收缓存为 64KB;问甲从连接建立成功到发送窗口达到 32KB 至少需要多久。

乙接收缓存 64KB,足够大,不限制发送窗口。所以发送窗口主要由拥塞窗口决定。

连接建立成功后,TCP 从慢开始开始增长:

初始 cwnd = 1KB
1RTT 后:2KB
2RTT 后:4KB
3RTT 后:8KB
4RTT 后:16KB
5RTT 后:32KB

每个 RTT 是 5ms,所以达到 32KB 至少需要:

5RTT × 5ms = 25ms

答案选 A。

这题的易错点是把三次握手时间也加进去,算成 30ms。但题目说的是“从连接建立成功至发送窗口达到 32KB”,所以三次握手已经完成,不再额外计算连接建立过程。


50 题:快速重传收到 3 个重复 ACK 后触发

题干说:

客户端在 t0 时刻第一次收到确认序号 ack_seq = 100 的段,并发送 seq = 100 的段,但该段丢失。后续客户端继续发送 seq = 200seq = 300seq = 400 等段。

服务器没有收到 seq = 100,却收到了后面的乱序数据段,因此它会反复确认自己“还想要 100 号开始的数据”,即连续发送:

ack_seq = 100
ack_seq = 100
ack_seq = 100

快速重传的规则是:

发送方收到 3 个重复 ACK 后,不等超时,立即重传丢失的报文段。

注意,t0 时刻第一次收到的 ack_seq = 100 是正常 ACK,不算重复 ACK。之后的三个 ack_seq = 100 才是重复 ACK。

图中三个重复 ACK 到达客户端的时刻分别是:

t1:第 1 个重复 ACK
t2:第 2 个重复 ACK
t3:第 3 个重复 ACK

收到第 3 个重复 ACK 后,客户端立即重传 seq = 100 的段,所以重传时刻是:

t3

答案选 C。

本题的陷阱是把 t0 的 ACK 也算成重复 ACK。如果把 t0 算进去,就会误以为 t2 就触发快速重传。但快速重传强调的是“3 个重复 ACK”,第一个正常 ACK 不算。


51 题:SYN 会消耗一个序号

题干说:

甲主动连接乙,甲、乙选择的初始序号分别是:

甲:2018
乙:2046

TCP 三次握手过程如下:

第一次握手,甲发送 SYN:

甲 -> 乙:SYN,seq = 2018

SYN 报文段会消耗一个序号,所以乙确认甲的 SYN 时,确认号为:

ack = 2018 + 1 = 2019

第二次握手,乙发送 SYN + ACK:

乙 -> 甲:SYN + ACK,seq = 2046,ack = 2019

乙的 SYN 也会消耗一个序号,所以第三次握手中,甲要确认乙的 SYN,确认号为:

ack = 2046 + 1 = 2047

所以第三次握手 TCP 段的确认序号是:

2047

答案选 D。

这类题的固定结论是:

SYN 消耗 1 个序号
FIN 也消耗 1 个序号
普通 ACK 不消耗序号

52 题:最长时间按拥塞避免算

题干关键信息是:

TCP 连接已经建立;MSS = 1KB;RTT = 2ms;不出现拥塞;问拥塞窗口从 8KB 增长到 32KB 所需的最长时间。

题目问“最长时间”,说明要考虑最慢的增长方式。TCP 拥塞窗口增长有两种典型方式:

慢开始:每 RTT 约翻倍,增长快
拥塞避免:每 RTT 增加 1MSS,增长慢

要求最长时间,就按拥塞避免阶段计算。

MSS = 1KB,所以拥塞避免阶段每经过 1 个 RTT,拥塞窗口增加:

1MSS = 1KB

从 8KB 增长到 32KB,需要增加:

32KB - 8KB = 24KB

每 RTT 增加 1KB,所以需要:

24RTT

RTT = 2ms,因此总时间为:

24 × 2ms = 48ms

答案选 D。

这题的易错点是按慢开始计算。若按慢开始:

8KB -> 16KB -> 32KB

只需要 2RTT,也就是 4ms。但题目问的是“最长时间”,因此不能按慢开始,而应按拥塞避免计算。

这 7 题答案依次是:

题号答案
53C,4000
54B,TIME_WAIT
55D,60.0%,37.5%
56C,701~1000
57C,11 RTT
58D,1650 ms,75 ms
59D,60.04 s

下面逐题说。

53 题:SYN 和 FIN 都占用 1 个序号

题干说:

SYN 段序号为 1000,FIN 段序号为 5001,问甲向乙已经发送的应用层数据字节数。

TCP 中要记住一个考点:

SYN 占用 1 个序号,FIN 也占用 1 个序号,但真正的应用层数据只看中间的数据序号。

SYN 的序号是 1000,所以第一个应用层数据字节的序号是:

1001

FIN 的序号是 5001,说明 FIN 前面的最后一个数据字节序号是:

5000

所以应用层数据字节数为:

5000 - 1001 + 1 = 4000

也可以直接记:

应用层数据字节数 = FIN序号 - SYN序号 - 1
              = 5001 - 1000 - 1
              = 4000

所以第 53 题选 C。

容易错在把 SYN 当成不占序号,算成 4001;或者把 FIN 也算进应用层数据,都是错的。

54 题:主动关闭方收到对方 FIN 并回 ACK 后进入 TIME_WAIT

客户首先向服务器发送 FIN,说明客户是主动关闭方。

主动关闭方的状态变化主线是:

ESTABLISHED
→ FIN_WAIT_1
→ FIN_WAIT_2
→ TIME_WAIT
→ CLOSED

题目问的是:客户收到服务器发送的 FIN 段并向服务器发送 ACK 段后,客户状态转为什么?

收到对方 FIN 并回 ACK 后,主动关闭方进入 TIME_WAIT。

所以第 54 题选 B。

这里容易错选 CLOSE_WAIT。CLOSE_WAIT 是被动关闭方收到 FIN 后进入的状态,不是主动关闭方的状态。

55 题:有效载荷比例只算传输层首部开销

应用层数据为 12B。

UDP 首部固定 8B,所以 UDP 数据报总长度为:

12 + 8 = 20B

有效载荷比例为:

12 / 20 = 60%

TCP 首部最小为 20B。题目问“最大传输效率”,所以取最小 TCP 首部 20B,不考虑选项、时间戳等扩展字段。

TCP 段总长度为:

12 + 20 = 32B

有效载荷比例为:

12 / 32 = 37.5%

所以第 55 题选 D。

这题的坑在于不要把 IP 首部也加进去。题目问的是 UDP 数据报和 TCP 段实现的有效载荷效率,按传输层 PDU 计算。

56 题:接收窗口从 ack_seq 开始,但已发送的数据不能再算“继续发送”

题干信息:

甲已经发送:

seq = 501,数据长度 200B

所以甲已经发出的数据序号范围是:

501~700

后来甲收到乙发来的段:

ack_seq = 501
rcvwnd = 500B

TCP 的接收窗口含义是:接收方当前愿意接收的字节序号范围从 ack_seq 开始,长度为 rcvwnd。

所以乙当前通告的接收窗口范围是:

501~1000

因为:

501 + 500 - 1 = 1000

但题目问的是甲“可以继续向乙发送”的数据序号范围。甲已经发过 501~700,所以不能把 501~700 再算作“继续发送”。

因此还能继续发送的是:

701~1000

所以第 56 题选 C。

这题最容易错选 A。A 是接收窗口范围,不是还能继续新发送的数据范围。

另外,乙发来的 seq = 601 是乙自己方向上的序号,和甲向乙还能发送哪些数据没有直接关系。做这类题时,ack_seqrcvwnd 才是关键。

57 题:超时后慢开始到门限,再拥塞避免线性增长

题干说:

MSS = 1KB
cwnd = 16KB 时发生超时

TCP 超时后的处理:

ssthresh = 原 cwnd / 2 = 8KB
cwnd = 1 MSS = 1KB

然后进入慢开始阶段,cwnd 每经过 1 个 RTT 翻倍:

初始:1KB
1 RTT 后:2KB
2 RTT 后:4KB
3 RTT 后:8KB

到达 ssthresh = 8KB 后,进入拥塞避免阶段,每经过 1 个 RTT 增加 1 MSS,也就是 1KB。

从 8KB 增长到 16KB,需要:

8 RTT

所以总时间为:

3 RTT + 8 RTT = 11 RTT

所以第 57 题选 C。

这题常见错法是直接按慢开始一直翻倍:

1 → 2 → 4 → 8 → 16

这样会得到 4 RTT,误选 A。但超时后设置了慢开始门限,达到 8KB 后不能继续翻倍,要改为线性增长。

58 题:主动关闭方 CLOSED 要加 2MSL,被动关闭方不用加 2MSL

题干:

RTT = 50ms
MSL = 800ms
C 主动关闭

从 C 发出 FIN 开始算。

C 是主动关闭方,过程是:

C 发 FIN
S 收到 FIN 后回 ACK,并在最短情况下也立即发 FIN
C 收到 S 的 FIN 后回 ACK,进入 TIME_WAIT
等待 2MSL 后进入 CLOSED

C 从发 FIN 到收到 S 的 FIN,至少经过 1 个 RTT:

50ms

然后 C 进入 TIME_WAIT,再等待:

2MSL = 2 × 800ms = 1600ms

所以 C 进入 CLOSED 的时间为:

50 + 1600 = 1650ms

S 是被动关闭方。时间线可以这样看:

0ms:C 发 FIN
25ms:S 收到 FIN,回 ACK,并立即发 FIN
50ms:C 收到 S 的 FIN,回 ACK
75ms:S 收到 C 对自己 FIN 的 ACK,进入 CLOSED

因为单程传播时间是:

RTT / 2 = 25ms

所以 S 进入 CLOSED 的时间是:

75ms

所以第 58 题选 D。

这题的核心规律是:

主动关闭方进入 CLOSED:收到对方 FIN 后先 TIME_WAIT,再等 2MSL。

被动关闭方进入 CLOSED:收到自己 FIN 的 ACK 后即可 CLOSED,不需要 TIME_WAIT。

59 题:按 408 真题口径,建立连接 + 传数据 + 释放连接 + TIME_WAIT

题干:

RTT = 10ms
MSL = 30s
MSS = 1000B
报文长度 = 3000B
H 主动断开连接

先分段:

3000B / 1000B = 3 个 TCP 段

由于题目说忽略 TCP 段传输时延,所以 3 个段可以连续发送,数据传输阶段按 1 个 RTT 计。

按 408 真题常见口径:

连接建立:1 RTT

10ms

数据传输并收到确认:1 RTT

10ms

连接释放:2 RTT

20ms

主动关闭方 H 发送最后一个 ACK 后进入 TIME_WAIT,再等待:

2MSL = 2 × 30s = 60s

所以总时间为:

10ms + 10ms + 20ms + 60s
= 40ms + 60s
= 60.04s

所以第 59 题选 D。公开题库中该 2024 统考题对应答案也标为 D。(Dotcpp)

这题容易和第 58 题混在一起。第 58 题是明确从发 FIN 时刻开始,并且问双方进入 CLOSED 的时间;第 59 题是从请求建立连接开始,到主动方 H 最终 CLOSED 为止,统考解析按“连接释放阶段 2RTT + TIME_WAIT 2MSL”的整体口径计算。考场上按这个模型做,答案就是 60.04s。

第 60 题答案:A,2 段。
第 61 题答案:B,8 ms,16 ms。

第 60 题:TCP 还能继续发送多少个段?

这题考的是 TCP 发送窗口的可用大小,要同时考虑两个限制:

实际发送窗口 = min(拥塞窗口 cwnd, 接收窗口 rcvwnd)
还能发送的数据量 = 实际发送窗口 - 已发送但尚未确认的数据量

题干给出:

t₀ 时刻:
cwnd = 2000B
发送窗口 = 2000B
ssthresh = 8000B
MSS = 1000B

所以甲在 t₀ 时刻最多能连续发送 2000B,也就是 2 个 MSS。图中也确实发送了两个段:

第 1 段:seq = 2001,1000B 数据,范围是 2001 ~ 3000
第 2 段:seq = 3001,1000B 数据,范围是 3001 ~ 4000

乙在 t₁ 返回确认段:

ack_seq = 3001
rcvwnd = 4000B

ack_seq = 3001 的含义是:乙已经正确收到 3001 之前的数据,也就是已经收到字节 2001 ~ 3000,下一次希望收到的是 3001。

所以这个 ACK 只确认了第 1 个 TCP 段,第 2 个段还没有被确认。

此时甲还有未确认数据:

seq = 3001 的那一段仍未确认
未确认数据量 = 1000B

接下来考虑拥塞窗口变化。题目说 t₀ 时刻拥塞窗口为 2000B,拥塞控制阈值为 8000B。因为:

cwnd = 2000B < ssthresh = 8000B

所以此时处于慢开始阶段。慢开始阶段每收到一个新的确认,拥塞窗口增加 1 个 MSS。

甲在 t₁ 收到一个新的确认,所以:

新的 cwnd = 2000B + 1000B = 3000B

乙通告的接收窗口是:

rcvwnd = 4000B

因此此时甲的实际发送窗口为:

min(cwnd, rcvwnd) = min(3000B, 4000B) = 3000B

但是注意,窗口里已经占用了一个未确认的 TCP 段,也就是 seq = 3001 的那 1000B 数据。因此还能继续发送的数据量是:

3000B - 1000B = 2000B

又因为 MSS = 1000B,所以还能发送:

2000B / 1000B = 2 段

所以第 60 题选:

A. 2

这题最容易错在把 rcvwnd = 4000B 直接当成还能发送 4 段。实际上 TCP 发送方能发多少,既受接收窗口限制,也受拥塞窗口限制,而且还要扣掉已经发送但尚未确认的数据。这里真正限制发送的是拥塞窗口 cwnd = 3000B,不是接收窗口 rcvwnd = 4000B

第 61 题:UDP 和 TCP 请求 Time 服务最少需要多久?

这题考的是应用层服务使用 UDP 和 TCP 时的最少通信时延差异。

题干给出:

RTT = 8 ms

RTT 是往返时间,也就是一个报文从客户端到服务器,再从服务器返回客户端所需的时间。

如果使用 UDP,请求过程很简单:

客户端发送请求 → 服务器返回响应

UDP 不需要建立连接,所以只需要 1 个 RTT。

因此 UDP 请求服务的最少时间是:

1 RTT = 8 ms

如果使用 TCP,就要先建立连接。TCP 建立连接需要三次握手。从考研常规做法看,三次握手最少消耗 1 个 RTT。

然后客户端再请求服务,服务器返回响应,又需要 1 个 RTT。

所以 TCP 请求服务的最少时间是:

建立 TCP 连接:1 RTT
请求并收到响应:1 RTT

总时间 = 2 RTT = 16 ms

所以第 61 题选:

B. 8 ms,16 ms

这类题的快速判断方法是:

UDP:无连接,请求 + 响应,通常算 1 RTT
TCP:先建连接,再请求 + 响应,通常算 2 RTT

下面按题号直接解析。整体考点是 TCP 的累计确认、序号按字节编号、滑动窗口吞吐率、慢开始与超时处理。

第 1 题

确认报文段丢失,不一定会引起对应数据重传。

原因是 TCP 采用累计确认。确认号表示“接收方期望收到的下一个字节序号”,所以后续确认报文可以把前面已经正确收到的数据一起确认掉。

例如发送方发送了 1~1000 字节,接收方发 ACK=1001,但这个 ACK 丢了。随后接收方又收到 1001~2000 字节,并发 ACK=2001。发送方收到 ACK=2001 后,就知道 1~2000 字节都已正确到达,因此不会重传 1~1000 字节。

易错点在于:TCP 不是“每个 ACK 丢了就一定重传”,而是只有在超时或触发快速重传等情况下,才会重传数据。

第 2 题

题目问:如果收到的 TCP 报文段无差错,但失序到达,接收方可以怎么处理。

方法一:直接丢弃失序报文段

这种方法实现简单,不需要额外缓存失序数据,对接收方缓冲区压力小。

但缺点很明显:已经正确到达的数据被丢弃,之后发送方还要重传,浪费网络带宽,降低吞吐率,也会增加恢复时间。

方法二:先暂存在接收缓存中

这种方法是把失序报文段先放到接收缓存里,等缺失的报文段到达后,再把连续的数据一起交付给应用层。

优点是减少不必要的重传,提高链路利用率和传输效率。

缺点是接收方实现更复杂,需要额外缓存空间,还要管理失序报文段。

考研中一般认为,实际 TCP 实现通常会缓存失序报文段,但确认号仍然采用累计确认。例如缺少序号 120 开始的报文段,即使后面的 150 开始的报文段到了,确认号仍然只能确认到 120。

第 3 题

已知:

第一个字节序号为 10010。

总数据量为 3200B。

前两个报文段各携带 1000B。

最后一个报文段携带剩余数据,即 3200 – 2000 = 1200B。

TCP 报文段的序号是该报文段中第一个数据字节的序号。

所以:

第 1 个报文段:序号 10010,携带字节 10010~11009。

第 2 个报文段:序号 11010,携带字节 11010~12009。

第 3 个报文段:序号 12010,携带字节 12010~13209。

答案:

三个报文段的序号分别为:
10010,11010,12010

易错点是不要把“报文段序号”理解成第几个报文段,而是第一个数据字节的编号。

第 4 题

已知:

发送窗口最大为 64KB。

平均往返时间 RTT = 20ms。

信道带宽不受限,只受窗口和 RTT 限制。

最大传输速率:

最大速率 = 发送窗口大小 / RTT

按 1KB = 1024B:

64KB = 64 × 1024B = 65536B

最大速率 = 65536 × 8 / 0.02
        = 26214400 b/s
        ≈ 26.2 Mb/s

答案:

最大数据传输速率约为 26.2 Mb/s

如果题目或教材粗略按 1KB = 1000B,则结果为 25.6Mb/s。考研计算中若未特别说明,64KB 常按 64 × 1024B 处理。

第 5 题

已知:

信道带宽为 100Mb/s。

单个报文大小为 1000B。

发送窗口固定为 60,即最多连续发送 60 个报文段。

端到端时延为 20ms,这里通常理解为单程时延,因此往返传播时延约为 40ms。

单个报文段的发送时延:

1000B × 8 / 100Mb/s = 8000 / 100000000 s = 0.08ms

发送窗口中共有 60 个报文段,总数据量为:

60 × 1000B = 60000B = 480000 bit

第一个报文段的确认返回大约需要:

0.08ms + 2 × 20ms = 40.08ms

所以平均最大传输速率约为:

480000 bit / 0.04008s ≈ 11.98 Mb/s

信道利用率:

11.98 / 100 ≈ 11.98%

答案:

最大平均数据传输速率约为 11.98 Mb/s,近似为 12 Mb/s。

信道利用率约为 11.98%,近似为 12%。

做题时也常简化为:

速率 ≈ 60 × 1000 × 8 / 0.04 = 12Mb/s
利用率 ≈ 12%

易错点是把 20ms 直接当 RTT。题干说“端到端时延”,一般是单程时延,所以 RTT 应按 40ms 处理。

第 6 题

已知三个 TCP 报文段的序号分别为:

第一个:90
第二个:120
第三个:150

TCP 序号是该报文段第一个数据字节的序号。

1)第一、二个报文段中有多少数据?

第一个报文段从 90 开始,第二个报文段从 120 开始,所以第一个报文段的数据长度为:

120 - 90 = 30B

第二个报文段从 120 开始,第三个报文段从 150 开始,所以第二个报文段的数据长度为:

150 - 120 = 30B

答案:

第一、二个报文段中各有 30B 数据。

2)第二个报文段丢失,确认号是多少?

第一个报文段到达后,主机 B 已经收到 90~119 这 30 个字节。

接下来它期望收到的下一个字节序号是 120。

虽然第三个报文段从 150 开始也到达了,但由于 120~149 这部分数据丢失,TCP 采用累计确认,所以确认号仍然只能是 120。

答案:

确认序号为 120。

易错点是看到第三个报文段到了,就误以为确认号变成 180。TCP 的确认号必须确认“连续正确收到”的字节,不能跳过中间缺口。

第 7 题

已知:

接收窗口为 24KB。

MSS = 2KB。

RTT = 10ms。

所以接收窗口相当于:

24KB / 2KB = 12 MSS

慢开始阶段中,拥塞窗口通常按 RTT 指数增长:

初始 cwnd = 1 MSS

经过 1 个 RTT:cwnd = 2 MSS
经过 2 个 RTT:cwnd = 4 MSS
经过 3 个 RTT:cwnd = 8 MSS
经过 4 个 RTT:cwnd = 16 MSS

但接收窗口最多只允许 12 MSS,所以当 cwnd 增长到超过 12 MSS 时,实际发送窗口被接收窗口限制为 12 MSS。

因此到第 4 个 RTT 后,就可以发送第一个完整接收窗口。

时间 = 4 × 10ms = 40ms

答案:

需要 40ms。

易错点是把 24KB 当成 24 个 MSS。这里 MSS 是 2KB,所以完整窗口是 12 个 MSS。

第 8 题

已知:

慢开始门限初始为 12 MSS。

拥塞窗口达到 16 MSS 时发生超时。

TCP 超时后:

新的慢开始门限 ssthresh = 16 / 2 = 8 MSS
拥塞窗口 cwnd 重新置为 1 MSS

然后再次进入慢开始:

超时后初始:cwnd = 1

经过 1 个 RTT:cwnd = 2
经过 2 个 RTT:cwnd = 4
经过 3 个 RTT:cwnd = 8

达到门限 8 后,进入拥塞避免阶段,每个 RTT 增加 1 MSS:

经过 4 个 RTT:cwnd = 9
经过 5 个 RTT:cwnd = 10
经过 6 个 RTT:cwnd = 11
经过 7 个 RTT:cwnd = 12
经过 8 个 RTT:cwnd = 13
经过 9 个 RTT:cwnd = 14
经过 10 个 RTT:cwnd = 15
经过 11 个 RTT:cwnd = 16

答案:

需要 11 个 RTT。

易错点是超时后不是从 8 开始,而是 cwnd 重新变为 1,ssthresh 才变为原来的一半。

第 9 题

TCP 序号字段是 32 位,按字节编号,因此序号空间大小为:

2³² B

为了避免序号在最大分组存活时间内循环回来,要求在 120s 内发送的数据量不能超过 2³²B。

最大速率:

最大速率 = 2³² × 8 / 120
        ≈ 286331153 b/s
        ≈ 286 Mb/s

答案:

线路允许的最快速度约为 286 Mb/s。

题目给出 TCP 报文段载荷为 1500B,主要是为了提醒按报文段发送数据,但 TCP 序号本质上仍然是按字节编号。最终结果仍然由 32 位字节序号空间决定。

易错点是把 TCP 序号误认为“报文段编号”。TCP 序号不是第几个报文段,而是字节序号。

第 10 题

已知:

链路速率为 256kb/s。

端到端时延为 128ms,通常理解为单程时延。

因此 RTT 约为:

RTT = 2 × 128ms = 256ms = 0.256s

实际吞吐率为 128kb/s。

窗口大小满足:

吞吐率 = 窗口大小 / RTT

所以:

窗口大小 = 128kb/s × 0.256s
        = 32.768kb
        = 32768 bit
        = 4096B
        = 4KB

答案:

窗口大小为 4KB。

如果某些题解把 128ms 直接当作 RTT,则会得到 2KB。但本题表述是“端到端时延”,通常按单程时延处理,所以更合理答案是 4KB。

下面按 408 网络题的做法来拆。先给答案:

第 11 题:拥塞窗口为 9 KB
第 12 题:源端口 3368,目的端口 21;序号字段为 0x505FA906,确认号字段为 0x00000070 = 112;TCP 首部长度 20B;这是 FTP 控制连接的建立请求报文,发送方处于 SYN-SENT,整体属于 TCP 连接建立阶段。
第 13 题:由 H 发送的是 1、3、4;参与 TCP 建立过程的是 1、2、3,严格说第 3 个报文使连接建立完成;快速以太网传输时发生填充的是 3、5;S 已收到的应用层数据为 16B;表 2 对应表 1 中的第 5 个分组,到达 H 时经过 15 个路由器


第 11 题:TCP 超时后的拥塞窗口变化

题干条件是:

TCP 最大报文段长度 MSS = 1 KB
超时前拥塞窗口 cwnd = 18 KB
发生超时事件

TCP 拥塞控制中,一旦发生超时,通常按如下规则处理:

慢开始门限 ssthresh = 原拥塞窗口的一半 = 18 KB / 2 = 9 KB
拥塞窗口 cwnd = 1 MSS = 1 KB

然后重新进入慢开始阶段。慢开始阶段中,拥塞窗口按指数增长:

1 KB → 2 KB → 4 KB → 8 KB

再往后不能继续按指数直接冲到 16 KB,因为慢开始门限是 9 KB。达到慢开始门限后应转入拥塞避免阶段,所以第 4 次成功增长后窗口到达:

8 KB → 9 KB

因此答案为:

拥塞窗口 = 9 KB

这题容易错在把慢开始一直加倍,算成 16 KB。考研题里一般默认:慢开始增长到慢开始门限附近后,应转入拥塞避免,不能越过门限继续指数增长。


第 12 题:解析 TCP 首部十六进制字段

题目给出的 TCP 首部可按 20B 固定首部解析。这里图中换行处容易漏读,按 TCP 首部格式应理解为:

0D 28 00 15 50 5F A9 06 00 00 00 70 50 02 40 00 C0 29 00 00

如果缺少中间的 50,TCP 首部长度字段就不合法,所以按标准题意应按上面这一串解析。

TCP 首部字段顺序是:

源端口 2B
目的端口 2B
序号 4B
确认号 4B
数据偏移/保留/标志 2B
窗口 2B
校验和 2B
紧急指针 2B

1)源端口号和目的端口号

前 4 个字节是:

0D 28 00 15

其中:

源端口 = 0x0D28 = 3368
目的端口 = 0x0015 = 21

所以:

源端口号:3368
目的端口号:21

目的端口 21 是 FTP 控制连接端口,这一点后面判断应用层协议要用到。


2)发送序号和确认序号

接下来的 8 个字节是:

50 5F A9 06 00 00 00 70

其中:

序号 = 0x505FA906
确认号 = 0x00000070 = 112

所以答案为:

发送序号:0x505FA906
确认序号:0x00000070,即 112

不过要注意,后面标志位中 ACK = 0,所以这个确认号字段虽然有值,但在 TCP 语义上没有确认作用。考试问“确认号字段是多少”,答 112;若问“有效确认号是多少”,则应说明 ACK=0,确认号无效。


3)TCP 首部长度是多少?

关键看数据偏移字段。后面的字段是:

50 02

其中 0x50 的高 4 位是 5,表示 TCP 首部长度为 5 个 32 位字。

TCP 首部长度 = 5 × 4B = 20B

因此:

TCP 首部长度为 20B

这说明本报文没有 TCP 选项字段,只有固定首部。


4)这是使用什么协议的 TCP 连接?连接状态是什么?

目的端口号是:

21

端口 21 对应的是 FTP 控制连接,所以这是一个:

FTP 控制连接

再看标志位:

50 02

低位标志字段中:

SYN = 1
ACK = 0

这说明它是 TCP 三次握手中的第一个报文,即客户端向服务器发送的连接建立请求。

因此连接处于:

TCP 连接建立阶段

从发送方角度看,发送了 SYN 后进入:

SYN-SENT 状态

所以完整答案是:

这是 FTP 控制连接的建立请求报文;
发送方处于 SYN-SENT 状态;
它属于三次握手的第一个报文。

第 13 题:综合分析 IP 分组与 TCP 报文

题目给出:

H 的 IP 地址:192.168.0.8 = c0 a8 00 08
S 的 IP 地址:211.68.71.80 = d3 44 47 50

表 1 中每个 IP 分组都给出了前 40B,也就是 IP 首部 20B + TCP 首部前 20B。先抓住两个核心字段:

IP 首部中的源 IP 和目的 IP 可以判断方向;
TCP 首部中的标志位可以判断 SYN、ACK、PSH 等;
IP 总长度可以判断是否需要以太网填充。


1)哪些分组由 H 发送?

H 的 IP 是:

c0 a8 00 08

检查表 1 中每个分组的源 IP:

第 1 个分组:

源 IP = c0 a8 00 08
目的 IP = d3 44 47 50

所以第 1 个是 H 发给 S。

第 2 个分组:

源 IP = d3 44 47 50
目的 IP = c0 a8 00 08

所以第 2 个是 S 发给 H。

第 3 个分组:

源 IP = c0 a8 00 08
目的 IP = d3 44 47 50

所以第 3 个是 H 发给 S。

第 4 个分组:

源 IP = c0 a8 00 08
目的 IP = d3 44 47 50

所以第 4 个是 H 发给 S。

第 5 个分组:

源 IP = d3 44 47 50
目的 IP = c0 a8 00 08

所以第 5 个是 S 发给 H。

因此:

由 H 发送的分组:1、3、4

哪几个完成了 TCP 连接建立过程?

看 TCP 标志位。

第 1 个分组的 TCP 控制字段为:

70 02

其中 02 表示:

SYN = 1
ACK = 0

所以第 1 个是三次握手的第一个报文:

H → S:SYN

第 2 个分组的 TCP 控制字段为:

70 12

0x12 = 0x10 + 0x02,表示:

SYN = 1
ACK = 1

所以第 2 个是三次握手的第二个报文:

S → H:SYN + ACK

第 3 个分组的 TCP 控制字段为:

50 10

0x10 表示:

ACK = 1

所以第 3 个是三次握手的第三个报文:

H → S:ACK

因此参与 TCP 连接建立过程的分组是:

1、2、3

严格说,如果题目问“哪个报文使连接建立完成”,那就是:

第 3 个分组

因为三次握手的第三次 ACK 到达后,连接建立完成。


哪几个在快速以太网传输时进行了填充?

以太网帧的数据字段最小长度是 46B。IP 分组作为以太网帧的数据部分,如果 IP 分组长度小于 46B,就需要在数据链路层填充。

看 IP 首部中的总长度字段。

第 1 个:

总长度 = 0x0030 = 48B

48B 大于 46B,不需要填充。

第 2 个:

总长度 = 0x0030 = 48B

不需要填充。

第 3 个:

总长度 = 0x0028 = 40B

40B 小于 46B,需要填充 6B。

第 4 个:

总长度 = 0x0038 = 56B

不需要填充。

第 5 个:

总长度 = 0x0028 = 40B

40B 小于 46B,需要填充 6B。

所以:

需要以太网填充的分组:3、5

注意,填充发生在数据链路层,不会改变 IP 首部中的“总长度”字段。IP 总长度仍然是 40B,只是以太网帧为了达到最小帧长,在后面补了 6B。


2)S 已经收到的应用层数据字节数是多少?

这里要看 H 发给 S 的数据报文。

第 1 个分组是 SYN,没有应用层数据。
第 3 个分组是 ACK,没有应用层数据。
第 4 个分组是 H 发给 S 的数据报文。

第 4 个 IP 分组的总长度字段为:

0x0038 = 56B

IP 首部第一个字节是:

45

其中 5 表示 IP 首部长度为:

5 × 4B = 20B

TCP 首部控制字段前的字节是:

50

高 4 位是 5,表示 TCP 首部长度为:

5 × 4B = 20B

所以第 4 个分组中的 TCP 数据长度为:

TCP 数据长度 = IP 总长度 - IP 首部长度 - TCP 首部长度
TCP 数据长度 = 56B - 20B - 20B = 16B

这 16B 就是 H 发给 S 的应用层数据。

也可以用第 5 个分组的确认号验证。第 4 个分组中 H 的序号是:

84 6b 41 c6

第 5 个分组中 S 对 H 的确认号是:

84 6b 41 d6

差值为:

0x84 6b 41 d6 - 0x84 6b 41 c6 = 0x10 = 16

说明 S 已经确认收到 H 发来的 16B 数据。

因此:

S 已经收到的应用层数据字节数 = 16B

3)表 2 中来自 S 的分组到达 H 时经过了多少个路由器?

表 2 中来自 S 的分组首部为:

45 00 00 28 68 11 40 00 40 06 ...

其中 TTL 字段是:

40

注意这里是十六进制:

0x40 = 64

也就是说,分组从 S 发出时 TTL = 64。

表 2 对应表 1 中的第 5 个分组。第 5 个分组的 IP 首部中 TTL 字段为:

31

十六进制:

0x31 = 49

每经过一个路由器,TTL 减 1。因此经过的路由器数为:

64 - 49 = 15

所以:

该 IP 分组到达 H 时经过了 15 个路由器。

这里容易错在表 2 的目的 IP 和表 1 第 5 个分组的目的 IP 不一样。表 2 中目的 IP 是公网地址,表 1 第 5 个分组到达 H 时目的 IP 已变为 192.168.0.8,说明中间经过了 NAT 转换。虽然目的 IP 和目的端口被改写,但分组标识、序号、确认号、标志位等字段可以看出它对应表 1 的第 5 个分组。

本题本质是把 TCP 三次握手、序号变化、接收窗口、拥塞窗口慢开始、连接释放 放在一起考。关键是:H3 是发送方,S 是接收方;S 的接收缓存只有 20KB,并且数据只存入、不取出,所以 S 的通告接收窗口会一直变小,最后变为 0。

1)第二次握手段的 SYN、ACK 标志位和确认序号

H3 主动访问 Web 服务器 S,所以 H3 是 TCP 连接的主动发起方。

H3 建立连接时的初始序号为 100。第一次握手时,H3 向 S 发送:

SYN = 1
seq = 100

注意:TCP 中 SYN 本身要占用 1 个序号,所以 S 在第二次握手中确认 H3 的 SYN 时,确认号应为:

ack = 100 + 1 = 101

第二次握手是 S 发给 H3 的 SYN+ACK 报文段,因此:

SYN = 1
ACK = 1
确认序号 = 101

所以第 1 问答案是:

SYN = 1,ACK = 1,确认序号 = 101

这里最容易错的是忘记 SYN 要占用一个序号,误写成确认号 100。


2)H3 收到第 8 个确认段时,接收窗口和拥塞窗口是多少?

S 为该连接分配的接收缓存为 20KB,MSS = 1KB。H3 每次发送 1KB 的 TCP 数据段,S 每收到一个数据段就确认一次,并通告新的接收窗口。

由于 S 的接收缓存中数据只存入、不取出,所以每收到 1KB,剩余接收缓存就减少 1KB。

收到第 8 个数据段后,S 的接收缓存已经占用了:

8 × 1KB = 8KB

因此 S 通告给 H3 的接收窗口为:

20KB - 8KB = 12KB

所以第 8 个确认段通告的接收窗口是:

12KB

再看拥塞窗口。题目给出拥塞窗口阈值 ssthresh = 32KB,而当前数据量还没有达到这个阈值,因此 H3 处于慢开始阶段。

慢开始阶段中,每收到一个对新数据的 ACK,拥塞窗口 cwnd 增加 1 个 MSS。

初始拥塞窗口通常按 1 个 MSS 计算,即:

初始 cwnd = 1KB

收到第 8 个确认段后:

cwnd = 1KB + 8 × 1KB = 9KB

所以第 2 问答案是:

通告接收窗口 = 12KB
拥塞窗口 = 9KB

这里常见错误是把慢开始简单理解成“每轮 RTT 翻倍”,然后在“第 8 个 ACK”这个说法上算错。题目问的是第 8 个确认段,不是第 8 轮。


3)发送窗口等于 0 时,下一个待发送数据段的序号和平均速率

发送窗口由拥塞控制和流量控制共同决定:

发送窗口 = min(拥塞窗口 cwnd,接收窗口 rwnd)

S 的接收缓存一共 20KB,且只存入、不取出,所以当 S 收到 20 个 MSS 大小的数据段后,接收缓存被填满。

20KB / 1KB = 20 个数据段

此时 S 通告的接收窗口为:

20KB - 20KB = 0

H3 收到这个确认段后,发送窗口变为 0。

H3 的第一次握手 SYN 序号是 100,S 在第二次握手中确认到 101,因此 H3 发送的第 1 个数据字节序号是 101。

H3 总共已经发送了 20KB 数据,即:

20KB = 20 × 1024 = 20480 字节

所以下一个待发送数据段的序号为:

101 + 20480 = 20581

也就是说,此时 H3 等待发送的是第 21 个数据段,它的 TCP 序号是:

20581

接着算平均数据传输速率。

慢开始阶段的数据发送过程可以按 RTT 轮次理解:

t = 0:发送 1 个段,累计 1KB
t = 1RTT:收到 ACK,发送 2 个段,累计 3KB
t = 2RTT:收到 ACK,发送 4 个段,累计 7KB
t = 3RTT:收到 ACK,发送 8 个段,累计 15KB
t = 4RTT:收到 ACK,此时最多还只能再发送 5 个段,使 S 的 20KB 缓存刚好填满
t = 5RTT:收到第 20 个数据段的 ACK,S 通告接收窗口为 0,H3 发送窗口变为 0

题目给出 RTT = 200ms,所以:

5RTT = 5 × 200ms = 1000ms = 1s

从发送第 1 个数据段到发送窗口变为 0,H3 一共发送了 20KB 数据,因此平均数据传输速率为:

20KB / 1s = 20KB/s

如果换算成 bit/s:

20KB/s = 20 × 1024 × 8 bit/s = 163840 bit/s

即:

约 163.84 kb/s

所以第 3 问答案是:

下一个待发送数据段的序号 = 20581
平均数据传输速率 = 20KB/s,约等于 163.84 kb/s

这一问最容易错在两个地方:第一,忘记 SYN 占用一个序号,导致把下一个序号算成 20580;第二,只算到第 20 个数据段被发送出去,而没有等到 H3 收到“接收窗口为 0”的确认段。发送窗口变为 0 是发送方 H3 收到通告窗口为 0 的 ACK 后发生的,所以要算到 5RTT。


4)H3 请求断开连接后,S 释放连接的最短时间

H3 主动请求断开连接,所以 H3 是主动关闭方,S 是被动关闭方。

最短情况下,S 收到 H3 的 FIN 后,立即发送 FIN+ACK,不再等待应用层继续处理数据。

过程如下:

t 时刻:H3 发送 FIN

t + 0.5RTT:S 收到 H3 的 FIN,立即发送 FIN+ACK

t + 1RTT:H3 收到 S 的 FIN+ACK,立即发送 ACK

t + 1.5RTT:S 收到 H3 的最终 ACK,释放连接

RTT = 200ms,因此:

1.5RTT = 1.5 × 200ms = 300ms

所以第 4 问答案是:

S 释放连接的最短时间为 300ms

这里要注意:TIME_WAIT 是主动关闭方 H3 进入的状态,不是 S。S 收到最后一个 ACK 后即可释放连接,所以不能把 2MSL 算到 S 的释放时间里。


本题四问最终答案汇总:

1)SYN = 1,ACK = 1,确认序号 = 101

2)第 8 个确认段通告的接收窗口 = 12KB
   此时 H3 的拥塞窗口 = 9KB

3)发送窗口等于 0 时,下一个待发送数据段序号 = 20581
   平均数据传输速率 = 20KB/s = 163.84 kb/s

4)S 释放连接的最短时间 = 300ms
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇