web学习笔记编程技术学习与分享

TCP 三次握手与四次挥手

2026 年 09 月 26 日约 3 分钟阅读 网络与安全

三次握手是每本教材的第一章,但落到生产里的问题——SYN 洪水、TIME_WAIT 堆积、backlog 打满——都需要真正理解状态机才能排查。

三次握手为什么是三次

客户端                服务端
  │ ── SYN, seq=x ──→   │        SYN_SENT → 服务端 SYN_RCVD
  │ ←─ SYN+ACK ──────  │
  │    seq=y, ack=x+1
  │ ── ACK, ack=y+1 ─→   │        ESTABLISHED 双方

两次不够:服务端需要确认「客户端收到了我的 SYN+ACK」,否则无法区分「旧连接的重复 SYN」(历史失效报文)与「新连接」。第三次 ACK 就是这个确认。序列号的意义正在于此:每个方向的字节流都有编号,确认号表示「期望收到的下一个字节」,重复与乱序由此可判。

四次挥手与 TIME_WAIT

断开需要四次,因为 TCP 是全双工,每个方向独立关闭。主动关闭方最后进入 TIME_WAIT,停留 2MSL(通常 60 秒),原因有二:确保最后一个 ACK 若丢失、对方重发的 FIN 能被响应;让旧连接的报文在网络中自然消亡,避免污染下一个相同四元组的新连接。

高并发短连接服务(爬虫、压测机)会出现几万 TIME_WAIT。它们占用端口但不占应用资源,通常无需处理;确实堆积时优先改用长连接,而不是去改 tcp_tw_reuse。

两个运维落点

SYN 洪水:攻击者发 SYN 不回 ACK,服务端半连接队列被占满。内核参数 tcp_syncookies=1 用加密 Cookie 无状态应答,是标准防御。

backlog 打满:全连接队列(accept 队列)满时新连接被丢。现象是「偶发连接超时」。检查:

ss -lnt | grep :443      # Recv-Q 接近 Send-Q 就是打满
netstat -s | grep -i listen   # 看 overflow 计数是否增长

调大 somaxconn 与应用的 listen backlog,并确认应用 accept 速度跟得上——队列是缓冲不是解药。

抓包验证

tcpdump -i any port 443 -nn 直接看 SYN/SYN+ACK/ACK 与挥手序列。教科书上的状态图,在真实报文里对一遍,比背十遍都牢。

TCP网络协议