当TCP主动关闭套接字时,采用四步握手机制来彻底关闭连接。如图:
- 客户端主动关闭连接,发送FIN段到服务端。TCP状态由ESTABLISHED(连接状态)转为FIN_WAIT1(表示,发送的FIN需要确认)。
- 服务端接受FIN后,服务端的TCP状态由ESTABLISHED转为CLOSE_WAIT,并且回送ACK。
- 客户端接受确认ACK后,TCP状态由FIN_WAIT1转化为FIN_WAIT2(表示已经确认FIN,等待来自服务端的FIN请求)。
- 服务端发送FIN,TCP状态CLOSE_WAIT转为LAST_ACK(表示服务器在等待客户端的ACK)
- 结束到FIN后,客户端发送ACK并且将状态转会为TIME_WAIT
- 服务器接受ACK,TCP状态转为CLOSED(关闭)。过一段时间,客户端有TIME_WAIT转为CLOSED。
发送主动关闭的一方在最终转换消息时经历了一个TIME_WAIT状态,并且保持这个状态一段时间。TIME_WAIT状态存在打作用是什么?
- 确认对等端收到了最后的ACK。最后的ACK可能意外丢失,导致对等端认为FIN丢失,进而重传FIN。因此,这个状态可以对重传作出回应。
- 服务器发起主动关闭但不进入TIME_WAIT状态,而这时客户端崩溃重启,重启后立即发起重新连接。重连时使用上次端口号进行连接,两端通信时,所使用的序列号恰好与上次相同,这样当上次连接残留在路由器中的数据到达服务器(延时数据段),进行数据整合时出现混乱。 当存在TIME_WAIT状态时,服务器会拒绝客户端的连接请求,这样确保不会使用处于TIME_WAIT状态的TCP连接端口号来与客户端连接。
- 客户端发起主动关闭,而不处于TIME_WAIT状态。在这种情况下可能发起连接时重用以前的端口号,这样产生相同的问题。
- TIME_WAIT状态存在,意味着两端的连接依然存在,意味着在TIME_WAIT状态时依然保留四元组(源IP,源端口,目的IP,目的端口),两端不得使用这些端口建立连接。
TIME_WAIT状态主要用于:重传机制,避免相同序列号导致与上次延迟数据发生混,。