四次挥手
挥手开始前客户端与服务器都处于ESTABLISHED
状态,假设客户端先发起关闭请求:
- 第一次挥手:客户端发送一个 FIN 报文,报文中指定一个序列号,此时客户端处于
FIN_WAIT1
状态,即发出连接释放报文段,并停止发送数据,等待服务器确认。 - 第二次挥手:服务器收到 FIN 报文后,会发送 ACK 报文,并且将客户端的序列号 + 1作为 ACK 报文的序列号值,此时服务器处于
CLOSE_WAIT
状态,此时的 TCP 连接处于半关闭的状态,客户端到服务器的连接被释放。客户端收到服务器的确认后,进入FIN_WAIT2
状态,等待服务器发送的 FIN 报文。 - 第三次挥手:服务器也发送一个 FIN 报文给客户端,并且指定一个序列号。此时服务器处于
LAST_ACK
状态,等待客户端确认。 - 第四次挥手:客户端收到 FIN 报文后,一样发送一个 ACK 报文作为应答,并且将服务器的序列号 + 1 作为 ACK 报文的序列号值。客户端进入
TIME_WAIT
状态,服务器收到应答后,直接进入CLOSED
状态。客户端在发送应答请求后,会等待一段时间,然后由TIME_WAIT
状态进入CLOSED
状态。
为什么不像三次握手那样,需要四次?
当服务器收到客户端的关闭报文后,并不会立即关闭socket,只会发送一个应答报文,表示收到了服务器的消息。当服务器的所有报文全部发送完毕后,服务器才能发起FIN
报文,申请关闭。
在第三次挥手和第四次挥手间,进行等待的目的?
为了保证第四次挥手成功地被服务端接收到。如果第四次挥手报文丢失,则服务器会重发第三次挥手的内容。这样还在等待中的客户端就可以接收到重发的保文,再次进行关闭尝试。