Appearance
题目
主机甲与主机乙之间已建立一个 TCP 连接,主机甲向主机乙发送了 3 个连续的 TCP 段,分别包含 300 字节、400 字节和 500 字节的有效载荷,第 3 个段的序号为 900。若主机乙仅正确接收到第 1 和第 3 个段,则主机乙发送给主机甲的确认序号是( )。
错因
A
误以为确认号 = 第 1 段的载荷长度 300——但确认号是序号空间里的位置,不是字节计数。第 1 段 seq 是 200(推算后),覆盖序号 200~499,下一个期待的序号是 500,不是 300。错的根源:把"载荷字节数"当成"序号位置"。
C
可能按"已接收的总字节"算:300(第 1 段)+ 500(第 3 段)+ 第 3 段 seq 900 - ... 凑成 1200。但 TCP 累计确认只计已连续收到的部分——第 2 段没收到,所以连续部分只到第 1 段末尾(500)。错的根源:把第 3 段当连续收到的一部分,但 TCP 不允许跳过第 2 段累计。
D
可能按"如果三段都收到"算:第 3 段 seq 900 + 500 字节 = 1400。但题面明确说"只收到第 1 和第 3 段"——第 2 段缺失,第 3 段不能用累计确认。错的根源:忽略第 2 段缺失,按全部接收的情形算确认号。
总解析
第一步:推算每段的序号范围
题面给出第 3 段 seq = 900。各段载荷:
| 段号 | 载荷字节数 | seq 范围 | 推算 |
|---|---|---|---|
| 1 | 300 | [seq₁, seq₁ + 299] | 由 seq₃ = 900 反推:seq₂ = 500、seq₁ = 200 |
| 2 | 400 | [500, 899] | |
| 3 | 500 | [900, 1399] |
详细推导:
- 设第 1 段 seq = ,覆盖
- 第 2 段 seq = ,覆盖
- 第 3 段 seq = = 900 →
所以:
| 段号 | seq 范围 | 状态 |
|---|---|---|
| 1 | [200, 499] | ✅ 收到 |
| 2 | [500, 899] | ❌ 缺失 |
| 3 | [900, 1399] | ✅ 收到(但失序) |
第二步:理清 TCP 累计确认规则
TCP 的 ACK 字段是累计确认——表示"我连续收到的字节中,下一个期待的序号"。只能确认到连续无间断的部分:
- 已连续收到:[200, 499](第 1 段)
- 第 2 段缺失 → 后续即使收到第 3 段也不能跳过累计
第三步:算确认号
注意:第 3 段虽然收到了,但因为第 2 段缺失,第 3 段处于"失序状态",会被接收方缓存(如果实现了),但不影响累计确认号的位置。
第四步:核对
| 选项 | 含义 | 错处 |
|---|---|---|
| A | 300 | 把载荷长度当成 ack |
| B | 500 | 正确(连续到 499,下一个期待 500) |
| C | 1200 | 凑数;误以为第 3 段也能累计 |
| D | 1400 | 假定全部收到(实际第 2 段缺失) |
最终答案是 B(500)。
编者注(生僻术语):TCP 的累计确认机制有时会"卡住"在缺失段——发送方收到多个相同的 ack(如本题甲会持续收到 ack=500),称为重复 ACK(duplicate ACK)。如果连续收到 3 个重复 ACK,发送方会触发快速重传(Fast Retransmit),不必等超时就重发缺失段。这是 TCP 拥塞控制中的标准优化。
另一种现代机制是 SACK(Selective Acknowledgment,RFC 2018)——TCP 选项里可以单独告诉发送方"第 3 段我也收到了,但缺第 2 段",发送方就只重传第 2 段,不重发第 3 段。SACK 让 TCP 更接近 SR 的效率。