TCP连接的终止需要挥手4次完成。 其过程如下图所示
(在此,假设退出有客户端开始,但可以在客户端或服务器端开始。)
也就是说,可以调换下图中的客户端和服务器的位置。 (第一次挥手
客户端向服务器发送FIN,客户端状态从ESTABLISHED更改为FIN_WAIT_1。
第二次挥手
服务器接收FIN并向客户端发送ACK。 服务器状态从ESTABLISHED更改为CLOSE_WAIT。
服务器继续向客户端发送未发送到缓存的数据
客户端收到ACK后,状态从FIN_WAIT_1变为FIN_WAIT_2。
第三次挥手
服务器向客户端发送FIN。 此时,服务器的状态从CLOSE_WAIT变为LAST_ACK。
第四次握手
客户端接收FIN并将ACK返回到服务器,客户端状态从FIN_WAIT_2更改为TIME_WAIT。 time _ wait=2MSL (maximumsegementlifetime分节在网络中的最长生存时间,30秒到2分钟,取决于系统的实现)
服务器收到ACK后,状态将从LAST_ACK更改为CLOSED。
客户端在经过TIME_WAIT时间后变为CLOSED状态。
为什么会有TIME_WAIT状态
1 .确保TCP全双工连接的终止。
假设最后一个ACK在网络上丢失。 但是,主动关闭的一方(上图为客户端)没有维护状态信息。 也就是说,如果没有TIME_WAIT,则直接变为CLOSED。 被动关闭端再次发送FIN,但如果客户端没有维护状态信息,将RST返回服务器,服务器将分析错误。 TIME_WAIT状态在最后一个ACK丢失的情况下是可能的,这是为了允许客户端在服务再次发送FIN时从新丢失的ACK发送到服务。
2 .允许旧的重复分节在网上消失。
假设12.106.32.254上的1500端口和206.168.112.219上的21端口之间存在TCP连接。 我们关闭了这个连接
过一会儿,在同一IP的同一端口上建立新的TCP连接。 此新TCP连接被视为旧TCP连接的头像(incarnation )。 为了避免这种情况,TIME_WAIT状态的持续时间为2MSL,这足以使某个方向的包生存并丢弃最长MSL秒。 此规则确保在建立新的TCP连接时,旧的重复数据包将在网络上丢失。
参考:
3359 blog.csdn.net/xingerr/article/details/72845941
UNIX网络编程(第三版)