TIME_WAIT状态

在TCP四次挥手中,有一个TIME_WAIT状态很有意思,在TCP连接的四次挥手中,首先客户端【或出现意外的服务器端】发送FIN包结束通信,服务器端返回ACK确认包,此时两次握手完毕。客户端单方面终止向服务器端发送消息和请求。TCP全双工的连接,此时其中一方的数据传输被独立关闭,成为半关闭状态【half close】

接下来,即服务器端想要结束数据传输,彻底关闭TCP连接,那么就执行剩下两次握手,服务器端首先向客户端发送FIN包,然后客户端接受,并返回ACK确认包【就如同前两次握手服务器端对客户端的反应那样】,但之后客户端并没有就此进入CLOSE状态,明明之后对于客户端来说没有任何需要发送和接收的工作,但客户端仍不能就此离开,而是进入了TIME_WAIT状态。

原因有二:
1.可靠的终止TCP连接
2.保证让迟来的TCP报文段有足够的时间被识别并丢弃。

第一点如何理解?
想想如果发生了这种情况,即客户端发送的ACK确认报文因意外丢失,那么服务器端将重发FIN报文段直到其收到想要的结果【即想要收到客户端的ACK确认包】,因此客户端需要停留在一个状态处理重复收到的结束报文段,这个状态即TIME_WAIT状态,否则,客户端将以复位报文段来回应服务器,服务器认为这是一个错误,因为他期望的是一个ACK确认报文段

而第二种情况,当一个TCP连接处于TIME_WAIT状态时,我们无法立即使用该连接占用着的端口来建立一个新连接。反过来思考,如果不存在TIME_WAIT状态,则应用程序能够立即建立一个和刚关闭的连接相似的连接【这里说的相似,是指它们具有相同的IP地址和端口号】。这个新的、和原来相似的连接被称为原来连接的化身【incarnation】。新的化身可能接受到属于原来的连接的、携带应用程序数据的TCP报文段【迟到的报文段】这里的迟到不一定是四次挥手中的,可能是两者在TCP整个通信过程中的任意一段发生意外而迟到的报文。这显然是不应该发生的,这就是TIME_WAIT状态存在的第二个原因。

参考资料:游双《Linux高性能服务器编程》

原文地址:https://www.cnblogs.com/kuronekonano/p/11135665.html