四次挥手在这张TCP状态转移图上是有两种情况,就是主动关闭和被动关闭。我直接先解释主动关闭。三体和地球用这个通道用了几千年,不好用,要拆了。为了损失最小化,两边要商量好。三体说,我不想用这个说话了,要不关了吧。第一次挥手。地球接到这个信号。地球还有一些事情没处理完,要借助这个通道。表示我知道了,但是我还有点事要处理,你等一会。这时是第二次挥手。处理完后,地球说:我处理好了,可以关闭了。这是第三次挥手。三体收到这两句话后,回复:我知道了。可以关闭了。这是第四次挥手。这整个过程我在写的时候老是有一种我知道你知道我知道了的那种感觉。正是这种反复确认,保证了TCP的可靠性。至于被动关闭就是三体和地球在某一天开战了,在开战的那一天,用这个通道在几乎同一时间互相发来战书。直接关闭了通道。

一、四次挥手涉及的核心状态

  • ESTABLISHED:数据传输完成后,双方处于的连接状态。
  • FIN_WAIT_1/2:主动关闭方发送FIN后进入的状态,等待对方的ACK或FIN。
  • CLOSING:双方同时发送FIN时的过渡状态。
  • TIME_WAIT:主动关闭方收到FIN并发送ACK后进入,需等待 “2MSL(最大报文段寿命)” 确保网络中残留的 TCP 报文段被耗尽。
  • CLOSE_WAIT:被动关闭方收到FIN后进入,等待应用层发起关闭操作。
  • LAST_ACK:被动关闭方发送FIN后进入,等待对方的ACK。

二、四次挥手的流程(主动关闭方为客户端,被动关闭方为服务器,角色可互换)

TCP 通过 “四次挥手” 关闭连接,本质是 ** 双方各自关闭 “发送方向”** 的过程,流程如下:

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

  • 主动关闭方(如客户端)从ESTABLISHED→FIN_WAIT_1,发送 **FIN报文 **(表示 “我没有数据要发了,请求关闭我的发送方向”)。

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

  • 被动关闭方(如服务器)从ESTABLISHED→CLOSE_WAIT,收到FIN后发送 **ACK报文 **(表示 “我知道你要关了,你等我处理完自己的关闭流程”)。
  • 此时,主动关闭方的 “发送方向” 已关闭,但被动关闭方仍可向主动关闭方发送数据(“半关闭” 状态)。

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

  • 被动关闭方应用层发起关闭后,从CLOSE_WAIT→LAST_ACK,发送 **FIN报文 **(表示 “我也没数据要发了,请求关闭我的发送方向”)。

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

  • 主动关闭方从FIN_WAIT_1→FIN_WAIT_2(若先收到ACK),再收到FIN后→TIME_WAIT,发送 **ACK报文 **(表示 “我知道你要关了,确认关闭”);
  • 主动关闭方等待2MSL后→CLOSED,完成关闭;被动关闭方收到ACK后→CLOSED,完成关闭。

三、特殊场景:同时关闭

若双方同时发送FIN,则进入CLOSING状态,互发ACK后进入TIME_WAIT,最终关闭(这是 “四次挥手” 的变体,本质仍是双方各自确认关闭)。

四、为什么需要 “四次挥手”?

因为 TCP 是双方可同时收发数据的通道,所以关闭连接时,需要分别关闭 “发送” 和 “接收” 两个方向

  • 第一次FIN:主动关闭方关闭 “发送方向”。
  • 第二次ACK:被动关闭方确认 “收到关闭请求”。
  • 第三次FIN:被动关闭方关闭 “发送方向”。
  • 第四次ACK:主动关闭方确认 “收到对方的关闭请求”。

这样的设计确保了双方都 “明确知道对方已关闭连接”,避免数据丢失或连接残留。

四次挥手在代码部分只与一个函数有关

四次挥手的核心逻辑由操作系统内核实现,应用层通过close()触发,具体对应关系:

挥手步骤

主动关闭方(客户端)操作

被动关闭方(服务器)操作

代码体现

1st

发送FIN,进入FIN_WAIT_1

-

客户端调用close(sock)

2nd

收到ACK,进入FIN_WAIT_2

回复ACK,进入CLOSE_WAIT

内核自动处理(无需代码)

3rd

-

发送FIN,进入LAST_ACK

服务器调用close(new_socket)

4th

回复ACK,进入TIME_WAIT

收到ACK,进入CLOSED

内核自动处理(无需代码)

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐