23-tcp协议——TIME_WAIT状态和FIN_WAIT2状态
23-tcp协议——TIME_WAIT状态和FIN_WAIT2状态
关于TIME_WAIT状态
TIME_WAIT是TCP状态转换中的一个非常重要的状态,TIME_WAIT状态的或多或少会极大的影响客户端与服务端的性能,在真实的应用场景中往往需要根据实际需求来对TIME_WAIT进行优化,因此在学习过程中有必要掌握TIME_WAIT状态。
为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
MSL(Maximum Segment Lifetime)表示报文段最大生存时间,它表示任何报文段被丢弃前在网络内的最长时间,实际上这个时间和 TTL 有关(TTL 是 IP 协议中的一个概念,表示能够经历的路由器的跳数,这个跳数是有限制的,最大值为 255)。但是MSL并不用跳数,而是用时间来计算。不同系统中,MSL 定义的大小不一样,RFC 规定,MSL = 2 分钟,而实际实现中,通常是 30 秒、1 分钟。也就是说报文在网络中存在的时间不能超过MSL规定的时间,同时也间接的说明了tcp连接在TIME_WAIT状态必须存在2MSL才能进入CLOSE状态。
图1-2MSL
2MSL的原因
2MSL的原因有2个:
1. 通常,当tcp释放连接的四个报文都发送完后,客户端和服务端双方就完全关闭连接,进入CLOSE状态。但是需要考虑一种情况:当四个报文都发送完毕时,客户端和服务器按理说应该进入CLOSE状态了,但是可能出现最后一个ACK丢失,即客户端发送的ACK在网络中丢失了,服务就永远都收不到最后的ACK,服务器也就无法关闭这个tcp连接
。
因此,TIME_WAIT状态就是用来重发可能丢失的ACK报文,也就是说2MSL计时器可以让客户端在丢失最后一个ACK确认时,等待服务器的下一个FIN到来,如果在TIME_WAIT状态中有一个新的FIN到来,那么客户端就发送一个新的ACK确认,并重新启动2MSL计时器。因为服务端收到客户端发送的ACK确认报文然后才进入close状态,如果一直没收到客户端发送的ACK确认报文,服务器则等待2MSL超时进入close状态(通常是
可能会
发送RST来关闭这条连接)
。
2. 假设客户端和服务端已经建立了一条连接1,如果没有TIME_WAIT状态,客户端和服务端马上又建立了连接2,这可能会造成连接2可能会接收到连接1的tcp数据报,从而产生一些错误。这时就需要加入TIME_WAIT状态,因为处于TIME_WAIT状态的端口在2MSL时间内无法建立新的连接(保证了在2MSL时间内只创建一个连接),只有当2MSL超时把连接1丢弃掉才能创建新的连接2, 这样就保证了每次只创建一个连接。
关于FIN_WAIT2状态
通常主动一方发起FIN报文,只要对端发送ACK确认后主动方就会处于FIN_WAIT2状态,然后等待对端发送FIN报文,如果一直没有发送FIN报文(就会一直处于CLOSE_WAIT状态,还有数据要发送,等等再关闭),那么主动一方就可能永远处于FIN_WAIT2状态,如图2所示。
图2-FIN_WAIT_2状态
为了解决主动一方永远处于FIN_WAIT2状态,操作系统设置了一个定时器,如果这个连接空闲时间超时了,那么该连接将进入CLOSED状态。
参考资料:https://blog.csdn.net/q1007729991/article/details/69686781