-
TIME_WAIT状态发生在客户端主动关闭连接时,发送最后一个ack后;CLOSE_WAIT状态发生在在Sever端收到Client的FIN消息之后。
-
出现 TIME_WAIT的状态原因
TIME_WAIT状态之所以存在,是为了保证网络的可靠性。由于TCP连接是双向的,所以在关闭连接的时候,两个方向各自都需要关闭。先发FIN包的一方执行的是主动关闭,后发送FIN包的一方执行的是被动关闭。主动关闭的一方会进入TIME_WAIT状态,并且在此状态停留2MSL时长。如果Server端一直没有向client端发送FIN消息(调用close() API),那么这个CLOSE_WAIT会一直存在下去。
-
出现CLOSE_WAIT的状态原因
假设最终的ACK丢失,server将重发FIN,client必须维护TCP状态信息以便可以重发最终的ACK,否则会发送RST,结果server认为发生错误。TCP实现必须可靠地终止连接的两个方向(全双工关闭),client必须进入 TIME_WAIT 状态,因为client可能面临重发最终ACK的情形。
-
为什么 TIME_WAIT 状态需要保持 2MSL 这么长的时间?
如果 TIME_WAIT 状态保持时间不足够长(比如小于2MSL),第一个连接就正常终止了。第二个拥有相同相关五元组的连接出现,而第一个连接的重复报文到达,干扰了第二个连接。TCP实现必须防止某个连接的重复报文在连接终止后出现,所以让TIME_WAIT状态保持时间足够长(2MSL),连接相应方向上的TCP报文要么完全响应完毕,要么被丢弃。建立第二个连接的时候,不会混淆。
答案解析
当client端传输完成数据,或者需要断开连接时:
-
Client端发送一个FIN报文给Server端。表示要终止Client到Server这个方向的连接。通过调用close(socket) API。表示Client不再会发送数据到Server端。(但Server还能继续发给Client端)。Client状态变为FIN_WAIT_1。
-
Server端收到FIN后,发送一个ACK报文给Client端(序号为M+1)。Server状态变为CLOSE_WAIT,Client收到序号为(M+1)的ACK后状态变为FIN_WAIT_2。Server端也发送一个FIN报文给Client端。(序号为N) 表示Server也要终止到Client端这个方向的连接。通过调用close(socket) API。Server端状态变为LAST_ACK。
-
Client端收到报文FIN后,也发送一个ACK报文给服务器。(序号N+1),Client状态变为TIME_WAIT。
-
Server端收到序号为(N+1)的ACK, Server的状态变为CLOSED。
-
等带2MSL之后,Client的状态也变为CLOSE。
至此,一个完整的TCP连接就关闭了。
注意:本文归作者所有,未经作者允许,不得转载