说一说四次挥手的过程?

1 个回答

  • 宁风致
    浪漫的灵魂从不向平淡的日子妥协。
    下面用“标准关闭(主动关闭方在左)”说明 TCP **四次挥手**: ``` 主动方(client) 被动方(server) 1) 发送 FIN,seq=u -> 收到后回 ACK(u+1) 状态:FIN_WAIT_1 状态:CLOSE_WAIT 2) 收到 ACK(u+1) <- 发送 ACK 状态:FIN_WAIT_2 (应用还可继续发送数据) 3) (等应用处理完) 发送 FIN,seq=v -> 状态:LAST_ACK 4) 发送 ACK(v+1) <- 收到 ACK 后 CLOSED 自己进入 TIME_WAIT(2MSL) (立刻 CLOSED) 时间到后 CLOSED ``` 要点: * TCP 全双工,**关闭是“方向”上的关闭**。一端发 `FIN` 表示“我这边不再发数据了”,但还能**继续收**,所以对方要在自己发送完后再发 `FIN`。这就是“4 次”而不是 3 次的原因(两个方向各需 `FIN`/`ACK`)。 * **TIME\_WAIT**:主动关闭方进入,停留 **2MSL**。目的: 1. 防止旧报文在网络中延迟后干扰新连接(端口四元组复用安全窗)。 2. 若对端没收到最后的 `ACK` 重发 `FIN` 时,**我们还能重发 ACK**。 常见状态速查(用 `ss -tan` 看): * `FIN_WAIT_1`:发出 `FIN`,等对端 `ACK/FIN`。 * `FIN_WAIT_2`:已收到 `ACK`,等对端 `FIN`(对端应用可能还在发数据)。 * `CLOSE_WAIT`:对端已关写;**本端应用还没 `close()`**。大量 `CLOSE_WAIT` 往往是**代码没及时关闭**连接。 * `LAST_ACK`:本端发出 `FIN`,等最后的 `ACK`。 * `TIME_WAIT`:主动关闭方等待 2MSL;大量短连接下常见。 * `CLOSING`:双方几乎同时发 `FIN` 的罕见状态;之后进入 `TIME_WAIT`。 变体与实战: * **半关闭**:`shutdown(SHUT_WR)` 只关发送通道,继续接收——协议层面完全合法。 * **同时关闭**:两端几乎同时发 `FIN`,会出现 `CLOSING`,随后 `TIME_WAIT`。 * **异常中断**:发送 `RST`(比如 `SO_LINGER=0` 直接复位),跳过挥手,用于快速中断。 * **TIME\_WAIT 很多怎么办**:优先**复用连接**(HTTP keep-alive、连接池);端口耗尽时再考虑系统参数与端口范围调整。 * **大量 `CLOSE_WAIT`**:检查业务代码是否忘记在读到 `-1` 或异常后 `close()`/归还连接。 一句话记忆:**FIN 表示“我不再发”,ACK 表示“我知道了”,两边各说一次,所以四次。**
    编辑于 2025-09-23 04:08 •IP属地 北京
    举报
    评论
    收藏