TCP中的TIME_WAIT状态
TIME_WAIT的存在有两大理由
1.可靠地实现TCP全双工连接的终止
2.允许老的可重复分节在网络中消失。
对于理由1,我们知道TCP结束需要四次挥手,若最后一次的客户端的挥手ACK丢失(假设是客户端发起断开TCP连接),服务器将重新发送它的最后那个FIN,因此客户必须维护状态信息,以允许它重新发送那个ACK(见下方例图1)。要是客户端不维护状态信息,它将响应一个RST(另一种类型的TCP分节),该分节将被服务器解释成一个错误。如果TCP打算执行所有必要的工作以彻底终止某个链接上两个方向的数据流,那么它必须正确处理连接终止序列4个分节中任何一个分节丢失的情况。这个例子也说明了为什么执行主动关闭的一端是处于TIME_WAIT状态的那一端:因为不得不重传最终ACK的就是那一端。
图1
对于第二个理由,我们假设在192.168.1.20的1500端口和46.19.0.201的21端口之间有一个TCP连接。我们关闭这个连接,过一段时间后在相同的IP和端口之间建立另一个连接。后一个连接称为前一个连接的化身,因为它们的IP地址和端口号都相同。TCP必须防止来自某个连接的老的重复分组在该连接已终止后再现,被误认为属于同一个连接的某个新的化身。为做到这一点,TCP将不给处于TIEM_WAIT状态的连接发起新的化身。既然TIEM_WAIT状态的持续时间是MSL的两倍,这足以让某个方向上的分组最多存活MSL秒即被丢弃,另一个方向上的应答最多存活MSL秒也被丢弃,通过实施这样的规则,我们就可以保证每次成功建立一个连接时,来自该连接先前化身的老的重复的分组都已经在网络中消逝了。
MSL(maximum segment lifetime): 最长分节生命期。
TCP无法仅仅通过查看目的端口号来分离外来的分节到不同的端点,它必须查看 套接字对 的4个元素(本地IP地址,本地TCP端口号,外地IP地址,外地TCP端口号)才能确认由哪个端点接受某个到达的分节。