Skip to content

窗口与序号:按 RTT 切片记一本账,每一小问都是查表(专题总纲)

Intro

这一类题的题面多半是一长串参数:初始序号、MSS、RTT、初始阈值、接收缓存大小,然后问你「收到第 8 个确认段时拥塞窗口是多少」「至少要多长时间」。

参数多,是因为TCP 的状态全是累加出来的

序号累加的是字节,拥塞窗口累加的是轮次,总时间累加的是 RTT

累加意味着没有一步能跳过。想直接套个公式算出第 8 个确认段的窗口,基本都会错。但反过来说:只要把中间每一轮老老实实记下来,每一小问就都只是从表里读一个格子

这个专题真正要练的,就是把一张表画对。

三本账,记在同一张表上

记什么每一步怎么变
字节账seq 和 ackseq = 己方 ISN + 1 + 已发字节数;ack = 对方 ISN + 1 + 已收字节数(那个 +1 是 SYN 占掉的)
轮次账cwnd慢启动每轮翻倍,到阈值后每轮加 1 个 MSS
窗口账实际能发多少发送窗口 = min(cwnd, rwnd)

数据传输阶段把这三列并排画成一张表,横轴是 RTT 轮次,这一段就做完了大半。(握手和挥手那几段不按轮次走,要逐个报文段记,见下面的答卷样张。)2023 年那道的第 (4) 问,标准做法就是这么一张五行的表:

轮次  本轮 cwnd  本轮发段数  累计已发   状态
 1      1 MSS       1          1      慢启动
 2      2 MSS       2          3      慢启动
 3      4 MSS       4          7      本轮起 cwnd 已等于阈值,转拥塞避免
 4      5 MSS       5         12      拥塞避免
 5      6 MSS       6         18 ✓    文件发完

18000 B ÷ MSS 1000 B = 18 个段,第 5 轮末刚好发完。

但总时间不等于表的行数。 这道题的标准答案是 6 个 RTT = 60 ms——数据占 5 个轮次,前面还要加上三次握手的 1 个 RTT。表给出的是数据阶段的轮数,建连那一个 RTT 要单独补上。

发送窗口:两个窗口谁小听谁的

cwnd 是发送方自己算的,rwnd 是接收方通告的,实际能发多少取两者的较小值。 关键是:哪一个更小要算出来才知道,不能想当然。 两道真题给的正好是相反的答案:

年份题面给的接收侧条件那一刻 cwnd那一刻 rwnd发送窗口
2016接收缓存 20 KB,且只存不取9 KB12 KB9 KB,取的是 cwnd
2026接收窗口始终 1000 B涨过 2 MSS 之后1000 B1000 B,取的是 rwnd

2016 年那道明说「S 端的接收缓存仅有数据存入而无数据取出」,所以每收一个 MSS 通告的 rwnd 就减 1 KB,收到第 8 个确认段时降到 20 − 8 = 12 KB。看到这里很容易顺势答 12 KB——但同一时刻 cwnd 才慢启动到 1 + 8 = 9 KB,min(9, 12) 取的是 cwnd

2026 年那道则反过来:接收窗口恒为 1000 B = 2 个 MSS,cwnd 涨过 2 MSS 之后发送窗口就封顶在 1000 B(第一轮 cwnd 只有 1 MSS = 500 B,那一轮还没封顶)。

两个窗口都要算出来再取小,少算哪一个都会错。

必错点

SYN 和 FIN 各占一个序号,但不携带数据。 五道真题里有三道要用到它(2016、2023、2026):2023 年那道选的初始序号是 100,SYN 占掉 100 这个序号,所以文件 F 的第一个字节序号是 101。同理挥手时 FIN 也要占一个号,算最后那个 ACK 的确认序号时别漏。

确认序号说的是「我期待的下一个字节」。 把它当成「我收到的最后一个字节」去用,整问就会差 1。 2023 年那道问「收到确认序号 2101 时 cwnd 多少」,先换算:已收字节 = 2101 − 101 = 2000 B = 2 个 MSS,也就是收到了 2 个 ACK。先把确认序号翻译成「收了几个段」,再去查表。

cwnd 有按 ACK 和按 RTT 两种记法,同一道题里可能都要用。 还是 2023 年那道:第 (3) 问问「收到某个确认段时」,要按收到第几个 ACK 来记(慢启动每个 ACK 加 1 MSS,拥塞避免每个 ACK 加 1/cwnd 个 MSS);第 (4) 问问总时间,要按第几个 RTT 轮次来记(慢启动每轮翻倍,拥塞避免每轮加 1)。两种记法在轮末对得上,中途对不上——看清问的是哪个时刻

上面那张按轮次画的表读不出「收到第 2 个 ACK 时 cwnd 多少」这种问法,遇到问某个确认段的,要另起一张按 ACK 逐个记的表:慢启动阶段每个 ACK 加 1 MSS,进入拥塞避免后每个 ACK 加 1/cwnd 个 MSS。

GBN 的序号位数决定窗口上限。 2017 年那道的序号字段是 3 比特,所以发送窗口最大 231=7。选择重传则是对称窗口,上限为 2n1这两个上限别记混。

捎带确认下要同时读两个号。 2017 年那道的 Sx,yx 是自己的发送序号、y 是给对方的确认序号,两个号各走各的账。读图时把两列分开记,混在一起必乱。

一道题的答卷长什么样

以 2026 年那道为例。C 的 ISN = 1000,Si 的 ISN = 2000,MSS = 500 B,文件 2000 B,rwnd 恒为 1000 B。

握手的三行账——每一行写清 seq、ack、标志位:

① C → Si   SYN=1  seq=1000                 ← SYN 占用序号 1000
② Si → C   SYN=1 ACK=1  seq=2000  ack=1001 ← 期待 C 的下一个字节 1001
③ C → Si   ACK=1  seq=1001  ack=2001

数据阶段看窗口:文件 2000 B ÷ 500 B = 4 个段。cwnd 从 1 MSS 起按慢启动走,但

发送窗口=min(cwnd,rwnd)=min(cwnd,1000 B)

rwnd 恒为 1000 B = 2 个 MSS,所以从第二轮起每轮最多发 2 段,4 个段要 3 轮才发完(1 + 2 + 1)。

挥手也要记账,这一问分值不低,而且 FIN 和 SYN 一样占一个序号。四次挥手走完之后,C 收到的最后一个报文段是 Si 的那个 ACK;算它的 ack_seq 时,C 这一侧已发的字节加上自己那个 FIN 占的号,都要数进去。

时间从轮数读出来:建连 1 个 RTT + 数据 3 个轮次 = 4 个 RTT = 20 ms。别再额外加一个「等最后确认」的 RTT——最后一轮数据的确认就在那一轮的 RTT 里,已经算过了。

⚠️ 这里最容易出错的是把 cwnd 的增长直接当成实际发送量。cwnd 在涨,但每轮实际发出去的是 min(cwnd, rwnd)。表上要写两列,不能只写一列。

真题的两种形态

第一组 · 给参数记账(2016-41、2023-47、2026-47)——给初始序号、MSS、RTT、阈值、接收缓存,问某时刻的序号、窗口、总时间。做法就是上面那张表。这一组常和应用层拼在一起问:2023 年那道先问 FTP 的控制连接是持久的、数据连接是非持久的,以及登录时建立的那条是控制连接——三个判断各值一点分,和后面的序号计算互不影响

第二组 · 给图或给字节读账(2017-47、2012-47)——题面不给你参数,给你一张收发时序图(2017 年的 GBN 双向捎带确认),或者一串十六进制的分组内容(2012 年的五个 IP 分组)。做法是先把图或字节还原成一张表,再照第一组的方式记账

⚠️ 2017 年那道其实是数据链路层的题(甲乙双方跑 GBN,单位是帧不是字节),收进这个专题是因为记账手法完全一样。但窗口上限的规则不同:GBN 的发送窗口受序号位数限制,最多 2n1;TCP 没有这个限制,它由 cwnd 和 rwnd 决定。

2012 年那道值得单独说:它给的是 5 个 IP 分组的前 40 字节十六进制串,要你切出 IP 头和 TCP 头的字段,判断哪几个由 H 发出、哪几个完成了握手、S 收到了多少应用层数据。切字段用的是题面附的头部结构图,算字节数用的还是「确认序号减去那一段数据的起始序号」——工具变了,账没变。

交卷前扫一眼

横轴按 RTT 轮次画表 · 发送窗口 = min(cwnd, rwnd) 写两列 · SYN 和 FIN 各占一个序号 · 确认序号先翻译成「收了几个段」· 问的是第几个 ACK 还是第几轮,看清楚

配套内容

考纲要求、但这 5 道真题没有正面考过的(专题的巩固栏里配了题):

  • 丢包之后 TCP 的 cwnd 怎么变——两道给参数记账的题(2023、2026)都明确设定了「没有丢包、乱序和重传」,所以超时与三个重复 ACK 这两种拥塞事件下 cwnd 的不同处理,一次都没考过(2017 年那道确实考了超时重传,但那是数据链路层 GBN 的超时,不是 TCP 的拥塞控制)
  • 快重传与快恢复——三个重复 ACK 触发重传的完整时序
  • 选择重传协议 SR——真题只考过 GBN,SR 的对称窗口上限没考过
  • TIME_WAIT 等待 2MSL——真题问过挥手的次数和序号,也问过被动方释放连接最短要多久(2016 年那道,答 1.5 个 RTT),但主动关闭方为什么要等 2MSL、等多久,一次都没考过
  • 确认段自己丢了会怎样——真题设定里连数据段都不丢,更没考过「确认丢了但后一个确认覆盖了它,所以前面那些数据段其实不用重传」这一层
  • UDP——四道是 TCP,另一道(2017 年)是数据链路层的 GBN,UDP 一次都没出现;巩固栏里配了两道,一道读 UDP 头部字段,一道看分片重组

逐题精讲(建设中)——真题作答与 AI 判分入口见站内大题专题

真题练习