Appearance
题目
假设主机 H 通过 TCP 向服务器发送长度为 3000 B 的报文,往返时间 RTT = 10 ms,最长报文段寿命 MSL = 30 s,最大报文段长度 MSS = 1000 B,忽略 TCP 段的传输时延,报文传输结束后 H 首先请求断开连接,则从 H 请求建立 TCP 连接时刻起,到 H 进入 CLOSED 状态为止,所需时间至少是( )
错因
A
把 TIME_WAIT 等待时间记成 1 MSL(30 s)——其实 TCP 规范明确规定 TIME_WAIT = 2 MSL = 60 s。记忆要点:2 MSL 的目的是确保最后那个 ACK 即使丢失,对方重传的 FIN 也能在 MSL 之内到达,本端再 MSL 内重发 ACK 仍能被收到,等价于"一个 ACK 来回的最坏时间"。把 30.03 s 也算了 3 RTT,但漏了慢启动那一步。
B
同 A 的错——把 TIME_WAIT 记成 1 MSL,但 RTT 数算到 4(含慢启动),凑出 30.04 s。等待时间错了一半。
C
TIME_WAIT 记对了 2 MSL = 60 s ✓,但漏算了慢启动——以为 3 个数据段可以在 1 RTT 内全部发出去并被全部确认。实际上 TCP 慢启动的初始 cwnd = 1 MSS,发送方第一轮只能发 1 段(拿到 ACK 后 cwnd 才升到 2,第二轮发剩下的 2 段),所以 3 段数据需要 2 RTT 而非 1 RTT。少算了 1 RTT 就是少了 10 ms,得到 60.03 s。
总解析
把"H 请求建立 TCP 连接"到"H 进入 CLOSED"切成四段串联:
① 三次握手(建立连接)
| 步骤 | 方向 | 用时 |
|---|---|---|
| SYN | H → 服务器 | 0.5 RTT |
| SYN+ACK | 服务器 → H | 1 RTT |
| ACK | H → 服务器(H 在此刻进入 ESTABLISHED) | — |
握手总耗时 = 1 RTT = 10 ms(H 在发出第三次 ACK 后就视为连接建立,不计 ACK 单程时延)。
② 数据传输(3000 B / 1000 B/段 = 3 段,慢启动起步)
| RTT | cwnd(段数) | 本轮发送 | 累计已传 |
|---|---|---|---|
| 第 1 RTT | 1 | 段 1 | 1 |
| 第 2 RTT | 2(拿到段 1 的 ACK 后翻倍) | 段 2、段 3 | 3 |
3 段数据在 cwnd 慢启动下需要 2 RTT = 20 ms。
③ 四次挥手(H 主动关闭)
| 步骤 | 方向 | 时刻(相对挥手起点) |
|---|---|---|
| FIN | H → 服务器 | 0 |
| ACK | 服务器 → H | 1 RTT 后 H 收到 |
| FIN | 服务器 → H(与上一项可合并到 1 个回程) | 1 RTT 后 H 收到 |
| ACK | H → 服务器,H 进入 TIME_WAIT | 1 RTT 后发出 |
H 从发出第一个 FIN 到进入 TIME_WAIT 用了 1 RTT = 10 ms(合并 ACK + FIN 的简化算法,408 默认采用)。
④ TIME_WAIT 等待 2 MSL
H 在 TIME_WAIT 状态等 2 × MSL = 60 s 后才进入 CLOSED。
汇总
最终答案是 D(60.04 s)。
编者注(生僻术语):TIME_WAIT 的"2 MSL"看起来抠门,其实是必要的——MSL 是单程极限,2 MSL 覆盖"最后 ACK 出去 + 万一对端没收到重发 FIN 进来"的两段路径。考研题里 MSL 常给 30 s(保守值,BSD 默认 60 s),所以 2 MSL = 60 s。本题用 30 s 即给出 60 s 的 TIME_WAIT,与 RTT 的几十毫秒比量级悬殊——只要题面提到了 MSL,TIME_WAIT 那一项就基本是答案的"主导项"。