与TCP三握手一样,TCP四挥手也是面试中频繁问到的知识点。
四挥手过程
在讲之前先来个四挥手的流程图看看:
刚开始双方都处于estsblished状态,客户端先发起关闭请求:
- 第一次挥手:客户端发送连接释放报文,并且停止发送数据,释放数据报文首部。发送FIN报文,指定序列号
**seq=u**,此时客户端进入FIN_WAIT_1状态。 - 第二次挥手: 服务器收到连接释放报文,发出确认报文,
ACK=1, ack=u+1,并且带上自己的序列号seq=v,此时,服务端进入了CLOSE_WAIT状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,此时处于半关闭状态,即客户端已经没有数据要发送了,但服务器若要发送数据,客户端依然要接受。 - 客户端收到服务器的确认请求后,此时,客户端就进入了
FIN_WAIT_2的状态,等待服务器发送连接释放报文(在此之前还需要接受服务器发送的最后的数据)。 - 第三次挥手:服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,
FIN=1,ack=u+1,由于在半关闭状态服务器很可能又发送了一些数据,假定此时的序列号为seq=w,服务器就进入了LAST_ACK(最后确认)状态,等待客户端的确认。 - 第四次挥手:客户端收到服务器的连接释放报文后,发出确认,
ACK=1,ack=w+1,而自己的序列号为seq=u+1,此时,客户端就进入了TIME_WAIT状态。注意此时TCP连接还没有释放,必须经过2*MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。 - 服务器在收到客户端的确认报文后,立即进入
CLOSED状态。同样,在撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间比客户端要早一些。
相关问题
- 为什么客户端在发送ACK后不直接关闭,而是等待一阵子?
原因是要确保服务器是否已经收到我们的ACK报文,如果没有收到的话,服务器会重新发FIN报文给客户端,客户端再次收到ACK报文后,就知道之前的ACK报文丢失了,然后再次发送ACK报文。
TIME_WAIT持续的时间至少是一个报文的来回时间。
