tcp状态——time wait

TIME_WAIT简介

tcp状态——time wait_第1张图片

TIME_WAIT通常也称为2MSL等待状态。这是因为切换到TIME_WAIT状态的socket会保持2倍的最大段生命周期(MSL)的延迟时间。MSL是TCP协议数据报中,任意一段数据在网络上被丢弃之前保持可用的最大时间。这个时间使用用于传输TCP段的IP数据报中的TTL字段进行设置,不同的实现为MSL设置了不同的值,通常为 30s,一分钟 或者 两分钟 。

TIME_WAIT影响

之所以TIME_WAIT能够影响系统的扩展性是因为在一个TCP连接中,一个Socket如果关闭的话,它将保持TIME_WAIT状态大约 4分钟 。如果很多连接快速的打开和关闭的话,系统中处于TIME_WAIT状态的socket将会积累很多,你可以使用netstat命令查看处于TIME_WAIT状态的socket。由于本地端口数量的限制,同一时间只有有限数量的socket连接可以建立,如果太多的socket处于TIME_WAIT状态,你会发现,由于用于新建连接的本地端口太缺乏,将会很难再建立新的对外连接。
你可以在socket级别使用SO_REUSEADDR socket选项解决TIME_WAIT的问题,这使得即使一个有着同样地址和端口的socket存在,也可以创建一个新的socket,新的socket最终将会劫持旧的socket。

TIME_WAIT存在原因

对于TIME_WAIT的存在,有两个理由。

1)为实现TCP这种全双工(full-duplex)连接的可靠释放
参考本文前面给出的TCP释放连接4次挥手示意图,假设发起active close的一方(图中为client)发送的ACK(4次交互的最后一个包)在网络中丢失,那么由于TCP的重传机制,执行passiveclose的一方(图中为server)需要重发其FIN,在该FIN到达client(client是active close发起方)之前,client必须维护这条连接的状态(尽管它已调用过close),具体而言,就是这条TCP连接对应的(local_ip, local_port)资源不能被立即释放或重新分配。直到romete peer重发的FIN达到,client也重发ACK后,该TCP连接才能恢复初始的CLOSED状态。如果activeclose方不进入TIME_WAIT以维护其连接状态,则当passive close方重发的FIN达到时,active close方的TCP传输层会以RST包响应对方,这会被对方认为有错误发生(而事实上,这是正常的关闭连接过程,并非异常)。
2)为使旧的数据包在网络因过期而消失
TCP连接由四元组唯一标识,因此,在我们假设的情况中,TCP协议栈是无法区分前后两条TCP连接的不同的,在它看来,这根本就是同一条连接,中间先释放再建立的过程对其来说是“感知”不到的。
假设TCP协议中不存在TIME_WAIT状态的限制,再假设当前有一条TCP连接:(local_ip, local_port, remote_ip,remote_port),因某些原因,我们先关闭,接着很快以相同的四元组建立一条新连接。这样就可能发生这样的情况:前一条TCP连接由local peer发送的数据到达remote peer后,会被该remot peer的TCP传输层当做当前TCP连接的正常数据接收并向上传递至应用层,从而引起数据错乱进而导致各种无法预知的诡异现象。
作为一种可靠的传输协议,TCP必须在协议层面考虑并避免这种情况的发生,这正是TIME_WAIT状态存在的第2个原因。

你可能感兴趣的:(网络协议)