TCP四次挥手以及TIME_WAIT的2MSL解析

TIME_WAIT

2018123022090138.png

毫无疑问,TCP中有关网络编程最不容易理解的就是它的TIME_WAIT。在上图中,我们看到执行主动关闭的那端经历了这个状态。该端点停留在这个状态的持续时间是最长分节生命期(maximum segment lifetime, MSL)的两倍。

任何TCP实现都必须为MSL选择一个值。RFC1122的建议是2分钟,不过源自Berkeley的实现传统上改用30秒。这意味着TIME_WAIT状态的持续时间在1分钟到4分钟。MSL是任何IP数据报能够在英特网中存活的最长时间。我们知道这个时间是有限的,因为每个数据报含有一个称为跳线(hop limit)的8位字段,其实就是TTL字段,对大值是255。尽管这是一个跳数限制,而不是真正的时间限制,但是我们仍然假设:255跳线的分组在网络中存在的时间不可能超过MSL秒。

分组在网络中”迷途“通常是路由异常的结果。某个路由器崩溃或某两个路由器之间的某个链路断开,路由协议花费数秒钟到数分钟的时间才能稳定并找出另一条通路。在这段时间内有可能发生路由循环(路由A把分组发送给路由B,而B再把它们发送回A),我们关心的分组就可能陷入此循环中。假设迷途的分组是一个TCP分节,在它迷途期间,发送端TCP超时并重新开始发送该分组,而重传的分组却通过某条候选路径到达最终目的地。然而不久后(自迷途的分组开始到最多MSL内)路由循环修复,早先迷失在这个循环中的分组最终被送到目的地。这个原来的分组被称为迷途的重复分组或漫游的重复分组。TCP必须正确处理这些重复的分组。

TIME_WAIT状态有两个存在的理由:

  1. 可靠的实现TCP全双工连接的终止
  2. 允许老的重复分节在网络中消逝

第一个理由可以假设最终的ACK丢失了来解释。服务器将重新发送它的最终那个FIN,因此客户必须维护状态信息,以允许重新发送最终那个ACK。要是客户不维护状态信息,它将响应以一个RST(另外一种类型的TCP分节),该分节将会被服务器解释为一个错误。如果TCP打算执行所有必要的工作以彻底终止某个连接上两个方向的数据流(即全双工关闭),那么它必须正确处理连接终止序列4个分节中任何一个分节丢失的情况。

第二个理由,我们假设在12.106.32.254的1500端口和106.168.112.219的21端口之间有一个TCP连接。我们关闭这个连接,过一段时间后在相同的IP地址和端口之间建立了另一个连接。后一个连接称为前一个连接的化身,因为它们的IP端口都相同。TCP必须防止来自某个连接的老的重复分组在该连接已经终止后再现,从而被误认为属于同一连接的某个新化身。为做到这一点,TCP将不给处于TIME_WAIT状态的连接发起新的化身。既然TIME_WAIT状态的持续时间是MSL的2倍,这就足以让某个方向上的分组最多村化MSL即被丢弃,另外一个方向上的应答最多存活MSL也被丢弃。通过实施这样的规则,我们就能保证每成功建立一个TCP连接,来自该连接先前的化身的老的重复分组已经全部在网络中消失了。

为什么是2MSL

因为客户端不知道服务端是否能收到ACK应答数据包,服务端如果没有收到ACK,会进行重传FIN,考虑最坏的一种情况:第四次挥手的ACK包的最大生存时长(MSL)+服务端重传的FIN包的最大生存时长(MSL)=2MSL


标题:TCP四次挥手以及TIME_WAIT的2MSL解析
作者:reyren
地址:https://www.reyren.cn/articles/2021/06/04/1623207272767.html

    评论
    0 评论
avatar

取消