企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## 四次挥手 ![](https://img.kancloud.cn/79/27/7927cbed07182edfdc5d0fd332f53bd7_1728x974.png) 1、客户端调用`close`方法,执行「主动关闭」,会发送一个 FIN 报文给服务端,从这以后客户端不能再发送数据给服务端了,客户端进入`FIN-WAIT-1`状态。FIN 报文其实就是将 FIN 标志位设置为 1。 FIN 段是可以携带数据的。不管 FIN 段是否携带数据,都需要消耗一个序列号。 客户端发送 FIN 包以后不能再发送数据给服务端,但是还可以接受服务端发送的数据。这个状态就是所谓的「半关闭(half-close)」 2、服务端收到 FIN 包以后回复确认 ACK 报文给客户端,服务端进入`CLOSE_WAIT`,客户端收到 ACK 以后进入`FIN-WAIT-2`状态。 3、服务端也没有数据要发送了,发送 FIN 报文给客户端,然后进入`LAST-ACK`状态,等待客户端的 ACK。同前面一样如果 FIN 段没有携带数据,也需要消耗一个序列号。 4、客户端收到服务端的 FIN 报文以后,回复 ACK 报文用来确认第三步里的 FIN 报文,进入`TIME_WAIT`状态,等待 2 个 MSL 以后进入`CLOSED`状态。服务端收到 ACK 以后进入`CLOSED`状态。 ## 为什么 FIN 报文要消耗一个序列号 如果 FIN 包不消耗一个序列号。客户端发送了 100 字节的数据包和 FIN 包,都等待服务端确认。如果这个时候客户端收到了ACK=1000 的确认包,就无法得知到底是 100 字节的确认包还是 FIN 包的确认包。 ## 为什么挥手要四次,变为三次可以吗 可以,因为有**延迟确认**的存在,把第二步的 ACK 经常会跟随第三步的 FIN 包一起捎带会对端。