TCP的三次握手和四次挥手

一、前言:为什么需要"握手"和"挥手"?

TCP 是面向连接、可靠的协议。在传输数据之前,双方必须先建立一条稳定的连接通道;数据传输完毕后,则需要优雅地关闭连接,以释放系统资源。这就是"握手"和"挥手"的目的。

在深入细节之前,我们先记住两个关键指针:

  • **SEQ (Sequence Number, 序列号):**用来标识发送的数据字节流,解决网络包乱序问题。
  • **ACK (Acknowledgment Number, 确认号):**告诉对方下一次期望收到的序列号,确认此前的数据已收到,解决丢包问题。

标志位:

  • **SYN:**用于建立连接(Synchronize)。
  • **ACK:**确认标识,确认收到数据。
  • **FIN:**用于断开连接(Finish)。

二、TCP 三次握手 (Three-way Handshake)

三次握手是连接建立的过程,其核心目标是:双方确认自己与对方的发送和接收能力都正常,并同步初始序列号 (ISN)。

详细过程:
1、第一次握手 (SYN)

  • 客户端 -> 服务器:发送一个 TCP 数据包。
  • 设置 SYN = 1,表示请求建立连接。
  • 选择一个初始序列号 SEQ = x (客户端 ISN)。
  • 客户端状态:SYN-SENT (同步已发送)。
  • 意图:"服务器,我想和你建立连接。我的初始序列号是 x。"

2、第二次握手 (SYN + ACK)

  • 服务器 -> 客户端:收到 SYN 包后,回应一个数据包。
  • 设置 SYN = 1 和 ACK = 1。
  • 选择自己的初始序列号 SEQ = y (服务器 ISN)。
  • 将确认号设置为 ACK = x + 1,表示已经收到客户端的 SYN。
  • 服务器状态:SYN-RCVD (同步已收到)。
  • 意图:"我同意建立连接。我的初始序列号是 y。我确认收到了你的序列号 x。"

3、第三次握手 (ACK)

  • 客户端 -> 服务器:收到服务器的 SYN-ACK 包后,再次回应。
  • 设置 ACK = 1。
  • 序列号 SEQ = x + 1 (因为第一次握手的 SYN 包消耗了一个序列号)。
  • 确认号 ACK = y + 1,表示已经收到服务器的 SYN。
  • 客户端 & 服务器状态:ESTABLISHED (连接已建立)。
  • 意图:"我确认收到了你的序列号 y。现在我们可以开始传输数据了!"

🤔 为什么是三次?两次不行吗?

关键在于第二次握手后,服务器并不知道客户端的接收能力是否正常。

如果只有两次握手:

  • 客户端发送一个 SYN 请求,但这个包在网络中滞留了(网络拥堵)。
  • 客户端超时重传了一个新的 SYN 请求,并与服务器正常完成了两次握手,传输数据后关闭了连接。
  • 此时,那个滞留在网络中的旧 SYN 请求终于到达了服务器。
  • 服务器会认为这是一个新的连接请求,于是回应 SYN-ACK,并进入 SYN-RCVD 状态等待客户端的 ACK。

**问题来了:**客户端早已关闭,根本不会理会这个回应。服务器将一直等待下去,浪费了宝贵的连接资源。

第三次握手的作用就是防止这种已失效的连接请求报文突然又传送到服务器,从而产生错误。它是对服务器连接请求的最终确认。只有客户端再次回应了,服务器才能确保连接是双方自愿且有效的,从而进入 ESTABLISHED 状态。

三、TCP 四次挥手 (Four-way Wavehand)

四次挥手是连接断开的过程。TCP 连接是全双工的,即数据可以同时在两个方向上传输。因此,每个方向都必须单独进行关闭。

详细过程:
1、第一次挥手 (FIN)

  • 主动关闭方 (通常是客户端) -> 被动关闭方:发送一个 FIN 包。
  • 设置 FIN = 1,序列号 SEQ = u。
  • 主动方状态:FIN-WAIT-1 (终止等待1)。
  • 意图:"我没有数据要发送了,我想关闭连接。"

2、第二次挥手 (ACK)

  • 被动关闭方 -> 主动关闭方:收到 FIN 包后,回应一个 ACK 包。
  • 设置 ACK = 1,确认号 ACK = u + 1。
  • 被动方状态:CLOSE-WAIT (关闭等待)。
  • 意图:"我知道你要关闭了,我同意。"
  • 此时状态:TCP 连接处于半关闭状态。即主动方已经不能再发送数据,但被动方可能还有数据要发送,主动方仍然必须接收。

3、第三次挥手 (FIN)

  • 被动关闭方 -> 主动关闭方:当被动方也没有数据要发送时,它会发送自己的 FIN 包。
  • 设置 FIN = 1,序列号 SEQ = v (v 是另一方独立的序列号)。
  • 被动方状态:LAST-ACK (最后确认)。
  • 意图:"我也发送完了,我也要关闭了。"

4、第四次挥手 (ACK)

  • 主动关闭方 -> 被动关闭方:收到 FIN 包后,回应最后一个 ACK 包。
  • 设置 ACK = 1,确认号 ACK = v + 1。
  • 主动方状态:进入 TIME-WAIT (时间等待) 状态。等待 2MSL (Maximum Segment Lifetime, 报文最大生存时间,通常为 2 分钟) 后,状态变为 CLOSED,彻底释放资源。
  • 被动方状态:收到最后一个 ACK 后,立即变为 CLOSED 状态。
  • 意图:"好的,再见。"

🤔 为什么是四次?挥手为什么需要 TIME-WAIT 状态?
为什么是四次?

因为 TCP 是全双工 的,关闭需要两个独立的过程。第二次和第三次挥手不能合并,是因为在第二次挥手(ACK)之后,被动方可能还有数据需要发送(CLOSE-WAIT 阶段),必须等所有数据都发送完毕,才能发送 FIN 包发起自己方向的关闭。

为什么需要 TIME-WAIT 状态?

这是 TCP 设计中最精妙的部分之一,主要有两个目的:

  • 可靠地终止连接:确保主动方发出的最后一个 ACK 能到达被动方。如果这个 ACK 丢失,被动方会超时重传它的 FIN 包。主动方在 TIME-WAIT 状态下收到重传的 FIN 后,可以重发 ACK。
  • 让旧连接报文消逝在网络中:等待足够长的时间(2MSL),确保本次连接所产生的所有报文都从网络中消失,从而防止旧连接的报文干扰新连接(和三次握手防止旧 SYN 包是同一个道理)。

四、总结与图示

三次握手

四次挥手

相关推荐
老蒋新思维7 小时前
创客匠人视角:智能体重构创始人 IP,知识变现从 “内容售卖” 到 “能力复制” 的革命
大数据·网络·人工智能·tcp/ip·创始人ip·创客匠人·知识变现
老蒋新思维10 小时前
创客匠人:认知即资产 ——AI 时代创始人 IP 知识变现的底层逻辑
网络·人工智能·网络协议·tcp/ip·重构·创始人ip·创客匠人
白驹过隙^^11 小时前
OB-USP-AGENT安装使用方法
数据库·经验分享·网络协议·tcp/ip·github·ssl
白帽子黑客罗哥11 小时前
渗透测试技术:从入门到实战的完整指南
网络·安全·web安全·渗透测试·漏洞挖掘·网络安全培训
北邮刘老师11 小时前
【智能体互联协议解析】ACPs/AIP为什么还在用“落后”的“中心化”架构?
网络·人工智能·架构·大模型·智能体·智能体互联网
winfield82111 小时前
MCP 协议详解
开发语言·网络·qt
sdszoe492211 小时前
IP地址规划与VLSM技术
网络·网络协议·tcp/ip·vlsm·ip地址规划
m0_5695310112 小时前
《K8s 网络入门到进阶:Service 与 Ingress 原理、部署方案及核心区别对比》
网络·容器·kubernetes
广东大榕树信息科技有限公司12 小时前
当运维管理面临挑战时,如何借助动环监控系统提升响应能力?
运维·网络·物联网·国产动环监控系统·动环监控系统
北京耐用通信12 小时前
耐达讯自动化网关:用Profinet唤醒沉睡的DeviceNet流量计,省下60%改造费!
人工智能·科技·物联网·网络协议·自动化·信息与通信