Appearance
题目
若客户首先向服务器发送 FIN 段请求断开 TCP 连接,则当客户收到服务器发送的 FIN 段并向服务器发送了 ACK 段后,客户的 TCP 状态转换为( )。
错因
A
CLOSE_WAIT 是被动关闭方收到 FIN 后的状态——服务器收到客户的 FIN 后进入 CLOSE_WAIT,等本端应用决定关闭。本题客户是主动方,主动方在挥手过程中绝不会进入 CLOSE_WAIT,这两条状态对应"哪一方发起关闭"是 TCP 状态机的硬区分。
C
FIN_WAIT_1 是客户刚发出 FIN 后的状态——客户发完 FIN,进入 FIN_WAIT_1 等待对端的 ACK 或 FIN。题面已经明确说"客户收到服务器 FIN 并发出 ACK"——这是挥手的最后一步动作,之后不可能还停留在 FIN_WAIT_1(那是开头的状态)。错的根源:把"挥手开始时"和"挥手结束时"两个时刻搞混了。
D
FIN_WAIT_2 是客户在 FIN_WAIT_1 收到对端 ACK(仅 ACK,未带 FIN)后的中间状态——这是"等对端的 FIN"。本题客户已经"收到 FIN 并发了 ACK",已经走过 FIN_WAIT_2 这一步,所以不应停在该状态。错的根源:把题面动作的最后一步(已发出 ACK)误解读为"还在等 FIN"。
总解析
TCP 主动关闭方的状态转换
ESTABLISHED
│ (发 FIN)
▼
FIN_WAIT_1
│ (收 ACK)
▼
FIN_WAIT_2
│ (收 FIN,发 ACK)
▼
TIME_WAIT
│ (等 2 MSL)
▼
CLOSED逐步分析本题客户的状态变迁:
| 步骤 | 客户动作 | 状态 |
|---|---|---|
| ① 客户发 FIN | 进入 FIN_WAIT_1 | FIN_WAIT_1 |
| ② 客户收到对自己 FIN 的 ACK | 进入 FIN_WAIT_2 | FIN_WAIT_2 |
| ③ 客户收到服务器的 FIN,并发出 ACK | 进入 TIME_WAIT | TIME_WAIT |
| ④ 等 2 MSL | 进入 CLOSED | CLOSED |
题面 "收到服务器 FIN 并发了 ACK 后" → 步骤 ③ 之后 → 标准状态 = TIME_WAIT。
特殊路径补充:即便客户在 FIN_WAIT_1 直接收到带 ACK 的 FIN(即对端把 ACK 和 FIN 合并发送,跳过 FIN_WAIT_2),客户也是直接转 TIME_WAIT;不会出现"卡在 FIN_WAIT_1"的情形。
最终答案是 B(TIME_WAIT)。
编者注(生僻术语):TCP 关闭分为四次挥手,其中"主动方"和"被动方"走完全不同的状态序列:
- 主动方:ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED(含 2 MSL 等待)
- 被动方:ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED(不需要 2 MSL)
主动方多走 TIME_WAIT 是为了:① 确保最后一个 ACK 能传到对端(万一丢了对端会重发 FIN,本端还能再发 ACK);② 让本次连接的"在飞分组"全部消失,避免新连接复用四元组时被旧分组干扰。