查看: 92|回复: 0

什么是 TCP 四次挥手?结合网页访问场景,看懂 TCP 可靠关闭全过程

[复制链接]

3075

主题

0

回帖

9264

积分

超级版主

积分
9264
发表于 2026-8-24 16:00:20 | 显示全部楼层 |阅读模式
摘要:浏览网页关闭标签页,网络连接并不会瞬间消失。TCP 作为可靠传输协议,断开连接需要一套完整协商流程,也就是我们常说的四次挥手。本文结合浏览器访问网页的真实场景,讲解 FIN、ACK 报文交互逻辑,解析CLOSE_WAIT、TIME_WAIT等 TCP 状态成因,帮你理解 TCP 如何安全释放连接,同时掌握线上网络问题排查思路。
前言

      我们每天打开浏览器访问网页,浏览器与 Web 服务器之间会建立 TCP 连接,用来传输 HTML 页面、图片、接口返回数据等各类内容。TCP 的核心特性是可靠传输:保证数据包按顺序送达,丢包自动重传,乱序报文重新排序。既然建立连接要保证可靠,关闭连接同样不能粗暴直接切断。如果直接一刀切断连接,很容易出现一种情况:一方认为数据已经全部发送完成,而另一方缓冲区中还有未传输完毕的数据,强制断开就会直接造成业务数据丢失CSDN博...。
      TCP 是全双工通信协议:同一条连接当中,客户端可以向服务器发送数据,服务器也可以向客户端回传数据,两个数据传输方向相互独立。关闭连接不等于拨动一个总开关,而是需要分别关闭两个方向的发送通道,这就是四次挥手产生的根本原因。
下面以日常场景举例:用户浏览网页,关闭浏览器标签页,浏览器作为客户端,成为主动关闭连接的一方,完整走完四次挥手流程。

四次挥手完整四步流程

概念说明:
  • FIN 报文:Finish,代表本方数据发送完毕,请求关闭本方发送通道
  • ACK 报文:Acknowledge,确认收到对方报文
  • 第一次挥手:客户端发送 FIN 报文浏览器(客户端)决定关闭连接,向服务器发送 FIN 报文。含义:我这边的数据已经发送完毕,我将关闭我到服务器的发送通道。⚠️注意:发送 FIN 不等于客户端直接销毁连接,仅仅代表后续不会再发送新业务数据。发送报文后,客户端进入FIN_WAIT_1状态。
  • 第二次挥手:服务器回复 ACK 确认报文服务器收到客户端的 FIN 报文,立刻返回 ACK 应答报文。含义:我收到了你不再发送数据的请求。到此,客户端→服务器这个方向的数据通道关闭。此时进入半关闭状态:客户端不再发送业务数据,但仍然可以接收服务器返回的数据,服务器还可以继续向客户端推送剩余数据。服务器进入CLOSE_WAIT状态;客户端收到 ACK 后切换到FIN_WAIT_2状态,等待服务器侧的关闭请求。
这里会出现时间间隔:第二步和第三步不一定紧挨着。服务器可能需要处理业务逻辑、读完缓冲区剩余数据、等待上层应用程序执行关闭操作,之后才会发起自己的关闭请求。
  • 第三次挥手:服务器发送 FIN 报文服务器业务处理完毕,缓冲区数据全部发送完成之后,向客户端发送 FIN 报文。含义:我这边的数据也全部发送完毕,我也要关闭我的发送通道。发送完成服务器进入LAST_ACK状态,等待客户端最后的确认回复。
特殊优化场景:如果服务器此时恰好没有任何剩余数据需要发送,第二步的 ACK 报文和第三步 FIN 报文可以合并为一次报文发送,看上去只有三次交互。但是逻辑层面依旧是两个独立动作,依然属于四次挥手的逻辑范畴。
  • 第四次挥手:客户端回复 ACK 确认报文浏览器收到服务器发来的 FIN 报文,回复 ACK 报文。含义:我收到你的关闭请求。服务器收到这条 ACK 报文之后,立刻释放 TCP 连接相关内核资源,服务器侧连接彻底关闭。而客户端并不会立刻释放连接资源,会进入TIME_WAIT状态,等待2MSL(报文最大生存时间,一般几十秒级别)之后,才最终切换到CLOSED,完成连接释放腾讯云。
简单记忆四句话:
  • 第一挥:主动方说,我发完了;
  • 第二挥:被动方说,我知道了;
  • 第三挥:被动方说,我也发完了;
  • 第四挥:主动方说,我也知道了。
核心逻辑:双方各自关闭自己的发送方向,并且每一次关闭请求,都需要对方给出确认回执,保障数据完整传输。
为什么需要 TIME_WAIT 状态?

很多人会疑惑,第四次挥手已经回复 ACK,为什么主动关闭方还要额外等待一段时间,不直接关闭?TIME_WAIT不是多余操作,是 TCP 可靠性设计的关键一环,有两大核心作用稀土掘金:
  • 保障最后一条 ACK 报文能够送达服务器网络存在丢包风险,如果第四步客户端发出的 ACK 报文在网络丢失,服务器收不到确认,会认为自己的 FIN 报文没有得到应答,超时之后就会不断重发 FIN 报文。客户端处在TIME_WAIT状态期间,内核还保留这条连接状态记录,收到服务器重传的 FIN,还可以再次补发 ACK 应答,保证连接正常收尾。如果客户端直接关闭,内核已经销毁连接记录,就无法响应重传 FIN,服务器会一直卡在LAST_ACK状态,造成资源泄漏。
  • 让网络中滞留的旧数据包自然过期网络存在延迟,旧连接的数据包有可能延迟很久才抵达目标主机。如果连接关闭之后立刻复用相同 IP + 端口建立新 TCP 连接,这些迟到的旧数据包,有可能被错误归属到新连接中,造成数据错乱。TIME_WAIT等待2MSL,可以保证网络链路当中属于旧连接的所有数据包全部过期消失,避免干扰后续新连接通信。
三次握手建立连接 VS 四次挥手关闭连接:为什么次数不一样?

  • 三次握手(建立连接):服务器收到客户端 SYN 请求,可以把「确认客户端 SYN」的 ACK 报文,和「服务器自身 SYN 建连请求」合并在同一个报文发送,因此只需要三次交互。
  • 四次挥手(断开连接):收到 FIN 的一方,不能立刻关闭自身发送通道,因为很可能还有业务数据需要继续传输。ACK 确认报文和 FIN 关闭报文大多数场景下无法合并,因此需要四次交互。
只有被动关闭方没有剩余数据,ACK+FIN 才可以合并,实现三次报文交互,但逻辑依旧是四次挥手逻辑CSDN博...。
常见 TCP 异常状态,线上故障排查参考

日常排查服务器网络问题,经常会看到大量CLOSE_WAIT、TIME_WAIT,理解四次挥手就可以快速定位问题根源。
  • 大量 CLOSE_WAIT现象:大量连接停留在CLOSE_WAIT状态。原因:客户端已经发送 FIN 关闭发送通道,但是服务器上层业务代码没有调用 socket 关闭接口。操作系统内核收到 FIN,回复 ACK 进入CLOSE_WAIT,等待应用程序处理,但是业务层迟迟不执行 close,不会发出 FIN 报文,连接就一直挂住,占用服务器文件描述符资源。解决:检查业务代码,确保连接使用完成之后及时关闭 socket,避免资源泄露。
  • 大量 TIME_WAIT现象:机器上充斥大量TIME_WAIT连接。原因:当前机器作为主动关闭连接的一方,大量短连接,每次请求结束都主动断开,就会产生大量TIME_WAIT。
注意:TIME_WAIT本身不是 BUG,是 TCP 正常保护机制。优化方向:开启 HTTP Keep‑Alive 长连接,使用连接池复用 TCP 连接,减少频繁创建销毁短连接;内核参数谨慎调整 tw_reuse 等参数,避免带来报文错乱风险。
现实场景补充:浏览器关闭标签页不一定立刻触发四次挥手

上面讲的四次挥手是标准 TCP 断开流程,但是现代浏览器实际行为会更复杂:
  • HTTP/1.1 支持 Keep‑Alive 长连接,关闭网页标签页,底层 TCP 连接不会立刻断开,浏览器会缓存连接,留给后续同域名请求复用,等待超时才会执行四次挥手释放。
  • HTTP/2 多路复用,单条 TCP 承载多个请求流,关闭页面仅仅结束业务流,底层 TCP 连接继续复用。
  • HTTP/3 基于 QUIC 协议,底层跑在 UDP 之上,关闭机制和 TCP 四次挥手完全不同。
总结:我们讨论的四次挥手,针对的是传统 TCP 协议的连接释放流程。
总结

四次挥手本质是 TCP 为了实现可靠关闭设计的一套协商流程。关闭网络连接不是简单 “断电式断开”,而是双方互相告知 “我这边没有数据要发了”,并且拿到对方确认回执,分别关闭两个方向的数据流。理解FIN、ACK报文,理解FIN_WAIT、CLOSE_WAIT、LAST_ACK、TIME_WAIT状态,不仅可以搞懂网络底层原理,在遇到接口超时、连接泄漏、服务器连接数爆满这类线上问题时,也可以快速定位故障点。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|天翼网

相关侵权、举报、投诉及建议等,请发 E-mail:2026@typc.net

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.|晋ICP备2026008270号-1|晋公网安备14010602111293号

QQ客服返回顶部