四次挥手图解

四次挥手的全部交互过程,具体如下图所示:
图:TCP建立的连接时四次挥手的示意图
处于TIME_WAIT状态的主动断开方,在等待完成2MSL的时间后,才真正关闭连接通道,其等待的时间为什么是2MSL呢?
2MSL翻译过来就是两倍的MSL。MSL全称为Maximum Segment
Lifetime,指的是一个TCP报文片段在网络中最大的存活时间,具体来说,2MSL对应于一次消息的来回(一个发送和一个回复)所需的最大时间。如果直到2MSL,主动断开方都没有再一次收到对方的报文(如FIN报文),则可以推断ACK已经被对方成功接收,此时,主动断开方将最终结束自己的TCP连接。所以,TCP的TIME_WAIT状态也称为2MSL等待状态。
有关MSL的具体的时间长度,在RFC1122协议中推荐为2分钟。在SICS(瑞典计算机科学院)开发的一个小型开源的TCP/IP协议栈——LwIP开源协议栈中MSL默认为1分钟。在源自Berkeley的TCP协议栈实现中MSL默认长度为30秒。总体来说,TIME_WAIT(2MSL)等待状态的时间长度,一般维持在1-4分钟之间。
通过三次握手建立连接和四次挥手拆除连接,一次TCP的连接建立及拆除,至少进行7次通信,可见其成本是很高的。

三次握手、四次挥手的常见面试题

有关TCP的连接建立的三次握手及拆除过程的四次挥手的面试问题,是技术面试过程中的出现频率很高的重点和难点问题,常见问题大致如下:

问题(1):为什么关闭连接的需要四次挥手,而建立连接却只要三次握手呢?

关闭连接时,被动断开方在收到对方的FIN结束请求报文时,很可能业务数据没有发送完成,并不能立即关闭连接,被动方只能先回复一个ACK响应报文,告诉主动断开方:“你发的FIN报文我收到了,只有等到我所有的业务报文都发送完了,我才能真正的结束,在结束之前,我会发你FIN+ACK报文的,你先等着”。所以,被动断开方的确认报文,需要拆开成为两步,故总体就需要四步挥手。
而在建立连接场景中,Server端的应答可以稍微简单一些。当Server端收到Client端的SYN连接请求报文后,其中ACK报文表示对请求报文的应答,SYN报文用来表示服务端的连接也已经同步开启了,而ACK报文和SYN报文之间,不会有其他报文需要发送,故而可以合二为一,可以直接发送一个SYN+ACK报文。所以,在建立连接时,只需要三次握手即可。

问题(2):为什么连接建立的时候是三次握手,可以改成两次握手吗?

三次握手完成两个重要的功能:一是双方都做好发送数据的准备工作,而且双方都知道对方已准备好;二是双方完成初始SN序列号的协商,双方的SN序列号在握手过程中被发送和确认。
如果把三次握手改成两次握手,可能发生死锁。两次握手的话,缺失了Client的二次确认ACK帧,假想的TCP建立的连接时二次挥手,可以如下图所示:
图:假想的TCP建立的连接时二次握手的示意图