题目
TCP 四次挥手的过程
答案
建立一个 TCP 连接需要三次握手,而终止一个 TCP 连接要经过四次挥手(也有将四次挥手叫做四次握手的)。这是由于 TCP 的**半关闭**(half-close)特性造成的,TCP 提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。 TCP 连接的释放需要发送四个包(执行四个步骤),因此称为四次挥手(`Four-way handshake`),**客户端或服务端均可主动发起挥手动作** ![TCP 四次挥手示意图](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/image-20230325164338973.png) 回顾一下上图中符号的意思: - `FIN` :连接终止位 - `seq`:发送的第一个字节的序号 - `ACK`:确认报文段 - `ack`:确认号。希望收到的下一个数据的第一个字节的序号 刚开始双方都处于`ESTABLISHED` 状态,假设是客户端先发起关闭请求。四次挥手的过程如下: **1)第一次挥手**:客户端发送一个【FIN 报文】(请求连接终止:FIN = 1),报文中的序列号 seq = x。并**停止再发送数据,主动关闭 TCP 连接**。此时客户端处于 `FIN_WAIT1` 状态,等待服务端的确认。 > 客户端的第一个 FIN 包的序列号 `seq` 是客户端在数据传输阶段最后一个报文的序列号加上它所携带的数据的字节数(如果没有携带数据,则是最后一个报文的序列号加1)。在四次挥手的过程中,客户端的第一个 FIN 包不携带数据,所以它的序列号 `seq` 可以简单理解为客户端在数据传输阶段最后一个报文的序列号加 1。 **2)第二次挥手**:服务端收到 FIN 之后,会发送【ACK 报文】,且把客户端的序号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 `CLOSE_WAIT` 状态。 **此时的 TCP 处于半关闭状态,客户端到服务端的连接释放**。客户端收到服务端的确认后,进入`FIN_WAIT2`(终止等待 2)状态,等待服务端发出的连接释放报文段。 **3)第三次挥手**:如果服务端也想断开连接了(没有要向客户端发出的数据),和客户端的第一次挥手一样,发送【FIN 报文】,且指定一个序列号。此时服务端处于 `LAST_ACK` 的状态,等待客户端的确认。 **4)第四次挥手**:客户端收到 FIN 之后,一样发送一个【ACK 报文】作为应答,且把服务端的序列值 +1 作为自己 ACK 报文的序号值,此时客户端处于 **`TIME_WAIT` (时间等待)状态**。 🚨 注意 !!!`TIME_WAIT` 状态下,服务端到客户端的 TCP 连接并未释放掉,**需要经过时间等待计时器设置的时间 2MSL(`MSL`:Maximum Segment Lifetime,报文最大生存时间) 后才会进入 `CLOSED` 状态**,服务端收到 ACK 报文之后,就关闭连接了,处于 `CLOSED` 状态。