TCP 连接管理
hard计算机网络TCP三次握手四次挥手TIME_WAIT
三次握手(建立连接)
TCP 使用三次握手(Three-Way Handshake)来建立可靠连接:
客户端 服务端
│ │
│ SYN=1, seq=x │
│ ─────────────────────────────────────────▶ │ ① 客户端发送 SYN
│ "我想建立连接,初始序号是 x" │ 状态: SYN_SENT
│ │
│ SYN=1, ACK=1, seq=y, ack=x+1 │
│ ◀───────────────────────────────────────── │ ② 服务端回复 SYN+ACK
│ "同意,我的初始序号是 y,确认你的 x" │ 状态: SYN_RCVD
│ │
│ ACK=1, seq=x+1, ack=y+1 │
│ ─────────────────────────────────────────▶ │ ③ 客户端发送 ACK
│ "确认你的 y" │ 状态: ESTABLISHED
│ │ 状态: ESTABLISHED
│ ── 连接建立,开始传数据 ── │
为什么是三次而不是两次?
防止已失效的连接请求突然到达服务端。假设只有两次握手:
场景: 客户端发送 SYN①,网络延迟导致超时
客户端重发 SYN②,成功建立连接并关闭
之后 SYN① 到达服务端
两次握手: 服务端收到 SYN① 就建立连接 → 但客户端早已不用了→ 资源浪费
三次握手: 服务端收到 SYN① 回复 SYN+ACK → 客户端不会发 ACK → 连接不成立 ✅
核心目的:确保双方都知道对方的接收和发送能力正常。
为什么不是四次?
三次已经足够同步双方的初始序号。第二步服务端将 SYN 和 ACK 合并在一个报文中发送,无需拆成两步。
四次挥手(关闭连接)
TCP 使用四次挥手(Four-Way Handshake)来关闭连接:
客户端 服务端
│ │
│ FIN=1, seq=u │
│ ─────────────────────────────────────────▶ │ ① 客户端请求关闭
│ "我没有数据要发了" │ FIN_WAIT_1
│ │
│ ACK=1, ack=u+1 │
│ ◀───────────────────────────────────────── │ ② 服务端确认
│ "收到,但我可能还有数据要发" │ CLOSE_WAIT
│ FIN_WAIT_2 │
│ │
│ ... 服务端继续发送剩余数据 ... │
│ │
│ FIN=1, seq=w │
│ ◀───────────────────────────────────────── │ ③ 服务端也请求关闭
│ "我也没数据了" │ LAST_ACK
│ │
│ ACK=1, ack=w+1 │
│ ─────────────────────────────────────────▶ │ ④ 客户端确认
│ TIME_WAIT (等 2MSL) │ CLOSED
│ → CLOSED │
为什么是四次而不是三次?
因为 TCP 是全双工协议,关闭连接需要双方分别关闭自己的发送通道。服务端收到 FIN 后可能还有数据要发送,所以 ACK 和 FIN 不能合并,需要分两步。
TIME_WAIT 状态
客户端发送最后一个 ACK 后,不会立即关闭,而是等待 2MSL(Maximum Segment Lifetime,通常 60 秒)。
为什么需要 TIME_WAIT?
- 确保最后一个 ACK 到达服务端:如果 ACK 丢失,服务端会重发 FIN,客户端在 TIME_WAIT 期间可以重发 ACK
- 防止旧连接的延迟数据影响新连接:等 2MSL 确保旧连接的所有报文都在网络中消失
TIME_WAIT 过多怎么办? 高并发短连接服务器可能产生大量 TIME_WAIT,占用端口资源。解决方案:
# Linux 内核参数调优
net.ipv4.tcp_tw_reuse = 1 # 允许复用 TIME_WAIT 连接
net.ipv4.tcp_max_tw_buckets # 限制 TIME_WAIT 连接数量
生产高频题
三次握手的过程和目的?
(1) 客户端发 SYN (2) 服务端回 SYN+ACK (3) 客户端发 ACK。目的:同步双方初始序号,确认双方收发能力正常,防止失效的历史连接建立。
为什么关闭连接要四次挥手?
TCP 是全双工的,每个方向的关闭是独立的。主动关闭方发 FIN 表示自己发完了,被动方 ACK 确认但可能还有数据要发,等发完再发自己的 FIN,对方再 ACK。
TIME_WAIT 的作用?
(1) 确保最后一个 ACK 能到达对端(丢失可重传),(2) 等待旧连接的延迟报文在网络中消失,防止影响新连接。