
刚开始双方都处于established状态,假如是客户端先发起关闭请求,则
1、第一次挥手:客户端发送一个FIN报文,报文中会指定一个序列号,此时客户端处于FIN_WAIT1状态
2、第二次挥手:服务器端收到客户端发送的FIN报文后,会发送一个ACK报文作为响应,且把客户端的序列号值+1作为ACK报文的序列号,表明已经收到了客户端的报文了,此时服务器端处于CLOSE_WAIT2状态。(被动关闭)
3、第三次挥手:如果服务器端也想断开连接了,和客户端的第一次挥手一样,服务器端也会发送FIN报文,并指定一个序列号。此时服务器端处于LAST_ACK的状态。
4、第四次挥手:客户端收到FIN报文后,会生成一个ACK报文作为应答,且把服务端的序列号+1作为自己ACK报文的序列号值,此时客户端处于TIME_WAIT状态,需要等待2MSL的时间,以确保服务端收到自己的ACK报文之后才会处于CLOSED状态
5、服务端收到ACK报文之后,就处于关闭连接了,处于CLOSED状态
这里特别需要注意的就是TIME_WAIT状态,
为什么客户端发送ACK之后不直接关闭,而是要等一阵子才关闭。这其中的原因就是,要确保服务器是否已经收到了我们的ACK报文,如果没有收到的话,服务器会重发FIN报文给客户端,客户端再次收到FIN报文之后,就会知道之前的ACK报文丢失了,然后再次发送ACK报文。
至于TIME_WAIT状态持续的时间至少是一个报文的来回时间。一般会设置一个计时,如果过了这个计时没有再次收到FIN报文,则代表对方成功接收ACK报文,此时处于CLOSED状态。
1、为了保证客户端发送的ACK报文能够顺利到达服务器端:
在TCP的四次挥手中的第四次挥手,客户端收到服务端发来的FIN报文,即返回一个ACK报文作为应答,且ACK的序列号为服务端的序列号+1,此时客户端的状态为TIME_WAIT状态,必须等待TIME_WAIT时间后,客户端的状态才变为CLOSED状态,因为客户端需要保证服务端收到自己的ACK报文,并使得服务端的状态由LAST_ACK状态变为CLOSED状态,如果服务端没有收到客户端的ACK报文,即客户端的ACK报文丢包,则服务端会重发FIN报文,使得双方都能正常进入CLOSED状态。(可靠地实现TCP全双工连接地终止)
2、防止已失效地连接请求报文出现在本次连接中(允许老的重复分组在网络中消逝)
