TCP 三次握手与四次挥手:从原理到状态机一次讲清

前言

TCP 是面向连接的可靠传输协议,连接的建立与释放分别通过「三次握手」和「四次挥手」完成。理解这两个过程,是掌握 TCP 状态机、排查网络问题以及应对面试的基础。

一、为什么 TCP 需要握手

TCP 通信前必须建立连接,核心目的是确认双方具备收发能力、同步初始序列号(ISN),并避免历史连接请求对当前连接造成干扰。序列号负责后续数据包的有序传递与可靠确认,因此双方都需要在连接建立阶段交换各自的初始序列号。

二、TCP 三次握手

三次握手的完整流程如下:

1. 第一次握手:客户端发送 SYN

客户端生成初始序列号 x,向服务器发送 SYN=1, seq=x 报文,随后进入 SYN_SENT 状态。

2. 第二次握手:服务器回复 SYN 和 ACK

服务器收到报文后,为该连接分配资源,生成自己的初始序列号 y,并回复 SYN=1, ACK=1, seq=y, ack=x+1,进入 SYN_RCVD 状态。

3. 第三次握手:客户端发送 ACK

客户端收到后,回复 ACK=1, seq=x+1, ack=y+1,自身进入 ESTABLISHED 状态。服务器收到该 ACK 后也进入 ESTABLISHED 状态,连接建立完成。

用时序图表示如下:

sequenceDiagram participant C as 客户端 participant S as 服务器 C->>S: SYN, seq=x S->>C: SYN+ACK, seq=y, ack=x+1 C->>S: ACK, seq=x+1, ack=y+1

为什么是三次握手而不是两次

两次握手无法可靠同步双方的初始序列号,也无法防止旧的连接请求造成干扰。例如,客户端第一次发送的 SYN 在网络中滞留很久后重新到达服务器,若服务器立即建立连接并回包,客户端却早已放弃该请求,就会产生一个无效连接。三次握手通过让客户端最终确认,避免这种历史报文被误用。

从能力验证角度看,三次握手后双方都能确认:自己的发送能力正常、接收能力正常,对方也具备收发能力。

三、TCP 四次挥手

TCP 支持全双工通信,两个方向的数据发送需要分别关闭,因此释放连接通常需要四次交互。

1. 第一次挥手:主动关闭方发送 FIN

主动关闭方发送 FIN=1, seq=u,进入 FIN_WAIT_1 状态。此后它不再发送数据,但仍可接收对方数据。

2. 第二次挥手:被动关闭方回复 ACK

被动方收到 FIN 后,回复 ACK=1, ack=u+1,进入 CLOSE_WAIT 状态。主动方收到 ACK 后进入 FIN_WAIT_2 状态。此时被动方到主动方的方向可能仍有数据在传输。

3. 第三次挥手:被动关闭方发送 FIN

被动方数据发送完毕后,发送 FIN=1, seq=v,进入 LAST_ACK 状态。

4. 第四次挥手:主动关闭方回复 ACK

主动方收到 FIN 后,回复 ACK=1, ack=v+1,进入 TIME_WAIT 状态,等待 2MSL 时间后关闭。被动方收到 ACK 后立即关闭连接。

用时序图表示如下:

sequenceDiagram participant C as 主动关闭方 participant S as 被动关闭方 C->>S: FIN, seq=u S->>C: ACK, ack=u+1 S->>C: FIN, seq=v C->>S: ACK, ack=v+1

为什么是四次挥手而不是三次

被动方收到 FIN 时,可能还有数据没有发送完毕,因此它需要先单独回复 ACK 表示「我收到了关闭请求」,等数据全部发送完成后再发送 FIN。这两个动作无法合并,所以挥手通常为四次。如果被动方恰好没有数据要发送,第二次的 ACK 和第三次的 FIN 可以合并,此时会退化为三次挥手。

TIME_WAIT 状态的作用

主动关闭方在发送最后一个 ACK 后会进入 TIME_WAIT 状态,并等待 2MSL 的时间,原因主要有两点:

  • 确保最后的 ACK 能被对方收到:如果该 ACK 丢失,被动方会重传 FIN,主动方仍有机会再次回复 ACK。
  • 让旧连接的数据包在网络中自然消失:避免同源同目的端口的旧数据包进入新连接,造成数据混乱。

四、常见问题梳理

问题 简要解释
第三次握手失败会怎样 服务器在 SYN_RCVD 状态重发 SYN+ACK,超过次数后释放半连接资源。
SYN 洪泛攻击如何防范 常见手段包括限制半连接数量、缩短 SYN 超时时间、启用 SYN Cookie 等。
为什么 TIME_WAIT 是 2MSL 保证最后一个 ACK 可达,并让旧连接报文在网络中消散。
挥手一定是四次吗 不一定,若被动方无数据发送,可将第二次和第三次合并,变为三次挥手。

五、总结

三次握手解决的是「连接能不能建立、初始序列号如何同步」的问题,四次挥手解决的是「两个方向的数据如何安全关闭」的问题。抓住状态变化这条主线,再结合实际抓包观察 SYN、FIN、ACK 报文,就能更直观地理解整个 TCP 连接的生命周期。

相关推荐
GreenTea8 小时前
GrokBot 核心成员 Lauren Tan:每月交付 2000 个 PR 的人,是怎么用 AI 的
前端·后端·架构
mCell9 小时前
用 Knip 清理 AI Coding 留下的冗余代码
前端·ai编程·前端工程化
笃行35010 小时前
使用Rokid AIUI做了一个童年推箱子游戏
前端
excel11 小时前
前端加密的作用与使用场景
前端
计算机魔术师12 小时前
纽约时报版权诉讼披露:微软高管内部称训练 AI 是人类历史上最大规模劳动窃取
前端
去伪存真12 小时前
大模型的参数量为什么那么大?
前端·人工智能
IT_陈寒13 小时前
Java空指针这次真把我坑惨了
前端·人工智能·后端
八荒启·交互动画14 小时前
# Web特效020—让 Web 特效真正动起来:时间循环应该怎么接
前端·webgl·网页特效·八荒启-交互动画·八荒启
动恰客流统计14 小时前
线下零售数字化浪潮下,客流统计的3个核心发展趋势
大数据·前端·人工智能