Posted by cluries on March 31st 2012
说说TCP中的TIME_WAIT状态
状态的形成
TIME_WAIT是一个比较纠结的状态:有三个状态可以转换成为它,分别是FIN_WAIT_1 、 FIN_WAIT_2和CLOSING.
1:由FIN_WAIT_1进入TIME_WAIT状态
在FIN_WAIT_1状态时候,收到了对方同时带FIN标志和ACK标志的报文时,那么将会发送ACK,同时直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。
2:由FIN_WAIT_2进入TIME_WAIT状态
在FIN_WAIT状态时候,接收到对方的FIN标志报文,那么将会发送ACK报文,同时进入TIME_WAIT状态.
3:由CLOSING进入TIME_WAIT状态
CLOSING这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。这种情况下只要接收到了对方发送的ACK,那么将会进入TIME_WAIT状态.
状态的作用
UNP上的对TIME_WAIT状态存在的理由列举有2条:
- 可靠的实现TCP全双工连接的终止
- 允许老的重复分节在网络中消逝
怎么解释TIME_WAIT状态可以可靠的实现TCP全双工连接的终止呢.
假设LAST_ACK丢失,被动关闭的一方将会重新发送他的最后的FIN,因此主动关闭的一方必须维护状态信息,用来允许它重新发送LAST_ACK.不然将会响应RST,而这个分解将会被被动关闭的一方解释为一个错误.如果TCP打算执行所有必要的工作来彻底终止两个方向上的数据流,他就必须正确处理连接终止序列4个分解中任何一个分节丢失的状况.
第二个理由,允许老的重复分节在网络中消逝.
假设某2个台机器在某端口之间已经建立了一个TCP连接,我们先关闭这个连接,一段时间以后,我们要在这2台机器上相同的端口重新建立一个连接,那么这个新建立的连接就是上一个连接的化身.
TCP必须防止某个连接的老的重复分组在这个连接已经终止后重新出现,从而被误解成为属于同一个连接的某个新的化身.
为了做到这点,TCP将不给处于TIME_WAIT状态的连接发起新的化身.因为TIME_WAIT的状态持续时间一般为MSL的2倍,那么就足以让某个方向上的分组最多存活MSL后被丢弃,另外一个方向上的应答最多存活MSL后也被丢弃.
这样,我们就能保证每次成功建立一个TCP连接时,来自该连接先前化身的老的重复分组都已经消逝于网络中了.