TCP 三次握手与四次挥手详解

1. 引言

TCP(Transmission Control Protocol,传输控制协议)是互联网中最核心的传输层协议之一,它为应用层提供可靠、面向连接的字节流服务。在 TCP 建立连接和断开连接的过程中,三次握手与四次挥手是两个最基础也最重要的机制。理解这两个过程,是深入掌握网络编程、排查连接异常的前提。

2. TCP 报文段中的关键标志位

在讲解握手与挥手之前,先了解 TCP 报文段头部中几个关键标志位,它们是整个流程的核心。

  • SYN(Synchronize):同步标志,用于建立连接时同步序列号。
  • ACK(Acknowledgment):确认标志,表示确认号有效,用于确认收到对方的数据。
  • FIN(Finish):结束标志,表示发送方数据已发送完毕,请求断开连接。
  • SEQ(Sequence Number):序列号,表示本报文段第一个字节的序号。
  • ACK Number(确认号):表示期望收到对方下一个字节的序号。

此外,TCP 连接是全双工的,即数据可以在两个方向上独立传输,因此连接建立和断开都需要在两个方向上分别确认。

3. 三次握手:建立连接

3.1 为什么需要三次握手

三次握手的核心目的有三个:

  • 确认双方的收发能力:确保客户端和服务端都能正确发送和接收数据。
  • 同步双方的初始序列号:为后续可靠传输奠定基础。
  • 防止历史失效连接请求:避免因网络延迟导致旧连接请求误建立新连接。

3.2 三次握手的具体过程

假设客户端为 A,服务端为 B,整个过程如下:

  1. 第一次握手(客户端发送 SYN):客户端向服务端发送一个 SYN 报文段,其中 SYN=1,并携带一个初始序列号 seq=x。此时客户端进入 SYN_SENT(同步已发送)状态。
  2. 第二次握手(服务端回复 SYN+ACK):服务端收到 SYN 报文后,如果同意建立连接,则回复一个 SYN+ACK 报文段,其中 SYN=1、ACK=1,确认号 ack=x+1,并携带自己的初始序列号 seq=y。此时服务端进入 SYN_RCVD(同步已接收)状态。
  3. 第三次握手(客户端回复 ACK):客户端收到 SYN+ACK 报文后,再向服务端发送一个 ACK 报文段,其中 ACK=1,确认号 ack=y+1,序列号 seq=x+1。此时客户端进入 ESTABLISHED(已建立连接)状态;服务端收到该 ACK 后也进入 ESTABLISHED 状态,连接正式建立。

3.3 三次握手的图示

3.4 为什么不是两次或四次

如果只有两次握手,服务端无法确认客户端是否收到了自己的 SYN+ACK 报文,也无法防止历史失效连接请求导致的资源浪费。而三次握手已经能够可靠地同步双方序列号并确认收发能力,四次则没有必要,反而增加延迟。因此三次握手是可靠性与效率之间的最佳平衡。

4. 四次挥手:断开连接

4.1 为什么需要四次挥手

由于 TCP 连接是全双工的,每个方向都必须独立关闭。当一方完成数据发送后,可以发送 FIN 报文关闭该方向的传输,但此时仍可以接收对方的数据。因此断开连接需要四次交互,分别关闭两个方向的数据通道。

4.2 四次挥手的具体过程

假设客户端主动发起断开连接,整个过程如下:

  1. 第一次挥手(客户端发送 FIN):客户端发送 FIN 报文段,其中 FIN=1,序列号 seq=u,表示客户端数据已发送完毕,请求断开连接。客户端进入 FIN_WAIT_1(终止等待 1)状态。
  2. 第二次挥手(服务端回复 ACK):服务端收到 FIN 报文后,回复 ACK 报文段,其中 ACK=1,确认号 ack=u+1,序列号 seq=v。此时服务端进入 CLOSE_WAIT(关闭等待)状态,客户端收到 ACK 后进入 FIN_WAIT_2(终止等待 2)状态。此时服务端仍可能继续发送数据。
  3. 第三次挥手(服务端发送 FIN):当服务端的数据也发送完毕后,服务端发送 FIN 报文段,其中 FIN=1,ACK=1,序列号 seq=w,确认号 ack=u+1。服务端进入 LAST_ACK(最后确认)状态。
  4. 第四次挥手(客户端回复 ACK):客户端收到 FIN 报文后,回复 ACK 报文段,其中 ACK=1,确认号 ack=w+1,序列号 seq=u+1。客户端进入 TIME_WAIT(时间等待)状态,服务端收到 ACK 后进入 CLOSED(关闭)状态。客户端在等待 2MSL(最大报文段生存时间)后进入 CLOSED 状态,连接彻底关闭。

4.3 四次挥手的图示

4.4 为什么客户端要等待 2MSL

客户端在发送最后一个 ACK 后进入 TIME_WAIT 状态,并等待 2MSL 时间,原因主要有两点:

  • 确保最后一个 ACK 能到达服务端:如果该 ACK 丢失,服务端会重发 FIN,客户端需要能够再次回复 ACK。若客户端立即关闭,则无法响应重发的 FIN。
  • 让旧报文在网络中自然消失:等待 2MSL 可以确保本次连接的所有报文段都在网络中消失,避免影响后续使用相同端口的新连接。

5. 常见问题与面试要点

5.1 三次握手中可以携带数据吗

第一次和第二次握手不能携带数据,因为此时连接尚未建立,若携带数据可能造成资源浪费和安全隐患。第三次握手时连接已基本建立,可以携带数据。

5.2 为什么挥手需要四次而握手只需要三次

握手时,服务端的 SYN 和 ACK 可以在同一个报文段中发送,因为服务端在收到 SYN 后可以立即同步自己的序列号并确认客户端的序列号。而挥手时,服务端收到 FIN 后可能仍有数据需要发送,因此 ACK 和 FIN 不能合并,需要分两次发送,所以挥手需要四次。

5.3 大量 TIME_WAIT 状态如何处理

在高并发场景下,主动关闭连接的一方可能出现大量 TIME_WAIT 状态的连接,占用端口资源。常见的优化手段包括:开启 TCP 时间戳选项、调整 MSL 值、复用 TIME_WAIT 连接(如开启 tcp_tw_reuse)等,但需结合具体业务场景谨慎使用。

6. 总结

三次握手通过 SYN、SYN+ACK、ACK 三次交互,可靠地建立了全双工连接并同步了双方序列号;四次挥手则通过 FIN、ACK、FIN、ACK 四次交互,分别关闭两个方向的数据通道,确保数据完整传输后安全断开。理解这两个过程,不仅有助于掌握 TCP 协议的本质,也是排查网络故障、优化服务性能的重要基础。

相关推荐
鸿蒙开发爱好者1 小时前
下班后做的小工具和小游戏,我把它们整理成了 WyanHub
网络·人工智能·职场和发展·个人开发
乐橙开放平台1 小时前
海康和大华摄像头能统一管理吗?可以通过 GB28181 或视频融合平台接入
网络·后端·物联网·音视频
星恒随风2 小时前
MySQL 从零入门(四):表的增删改查与基础查询详解
linux·服务器·数据库·笔记·mysql
张小姐的猫3 小时前
【基于 WebSocket 的多用户网页五子棋】—— 项目结构设计与实用工具类模块
网络·websocket·网络协议
QXWZ_IA4 小时前
测绘单位采购RTK:设备价格、账号年费、售后,用时间轴分权重
网络·人工智能·安全
IT大白鼠5 小时前
GitLab 未认证 RCE 应急实战CVE-2026-97229(CVSS 10.0)
网络·安全·gitlab
陈希1235 小时前
Linux 网络诊断工具实战:ping、curl、tcpdump、mtr、dig 用法详解
linux·网络·tcpdump
进击的荆棘5 小时前
Linux系统——线程同步与互斥之线程池和安全
linux·运维·服务器·安全·单例模式·线程
蜗牛一步步往上爬6 小时前
第六章 BMC常用的调试工具
服务器
小李不困还能学6 小时前
VSCode_RemoteSSH_一直卡在下载服务器_解决教程
服务器·ide·vscode