首先,TIME_WAIT并不是多余的。在TCP协议被创造,经历了大量的实际场景实践之后,TIME_WAIT出现了,因为TCP主动关闭连接的一方需要TIMEWAIT状态,它是我们的朋友。
为什么需要TIme_Wait
TCP协议要保证在所有可能的情况下使得所有的数据都能够被正确送达。当你关闭一个socket时,主动关闭一端的socket将进入TIME_WAIT状态,而被动关闭一方则转入CLOSED状态,这的确能够保证所有的数据都被传输。
当一个socket关闭的时候,是通过两端四次握手完成的,当一端调用close()时,就说明本端没有数据要发送了。这好似看来在握手完成以后,socket就都可以处于初始的CLOSED状态了,其实不然。原因是这样安排状态有两个问题, 首先,我们没有任何机制保证最后的一个ACK能够正常传输,第二,网络上仍然有可能有残余的数据包(wandering duplicates),我们也必须能够正常处理。
TIME_WAIT就是为了解决这两个问题而生的。
- 假设最后一个Ack丢失了,被动关闭的一方会重发它的FIN,主动关闭的一方要维持一个有效的状态信息。以便于能够重发确认。如果主动关闭的socket不维持这种状态而进入CLOSED状态,那么主动关闭的socket在处于CLOSED状态时,接收到FIN后会响应一个RST,被动关闭一方接收到RST后会认为出错了。这就是为什么socket在关闭后,仍然处于TIME_WAIT状态的第一个原因——等待以便重发ACK。
- 假设目前连接的通信双方都已经调用了close(),双方同时进入CLOSED的终结状态,而没有走TIME_WAIT状态。那么会出现如下问题:现