V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
jdz
V2EX  ›  程序员

为何 tcp 中的 time_wait 状态持续 2msl 而不是 msl 呢?

  •  
  •   jdz · 2020-01-23 22:03:36 +08:00 · 4146 次点击
    这是一个创建于 1526 天前的主题,其中的信息可能已经有所发展或是发生改变。
    了解为何需要 time_wait 状态,但是不清楚为何是 2msl
    9 条回复    2020-01-25 22:49:44 +08:00
    hfutzj
        1
    hfutzj  
       2020-01-23 22:27:49 +08:00 via Android
    仅供参考,有错误欢迎指出
    记得有两个原因,一个是保证所有消息生存期过了,二是保证最后发出的断开连接的消息对面能够收到
    palmers
        2
    palmers  
       2020-01-23 22:55:00 +08:00
    unix 网络编程卷 1 第 38 页摘录有
    1. 可靠地实现 TCP 全双工连接的终止。(确保最后的 ACK 能让被关闭方接收);
    2. 允许老的重复分节在网络中消逝。( TCP 中是可靠的服务,当数据包丢失会重传,当有数据包迷路的情况下,如果不等待 2MSL 时,当客户端以同样地方式重新和服务建立连接后,上一次迷路的数据包这时可能会到达服务,这时会造成旧包被重新读取)。
    jdz
        3
    jdz  
    OP
       2020-01-23 23:05:16 +08:00 via Android
    @palmers 这个我倒了解,但不了解为何要等这么久,而不是只等待 msl
    ChristopherWu
        4
    ChristopherWu  
       2020-01-23 23:06:17 +08:00
    总结:确保状态正确,也就是上面的同学说的 “保证最后发出的断开连接的消息对面能够收到”

    ```
    TCP A TCP B

    1. ESTABLISHED ESTABLISHED

    2. (Close)
    FIN-WAIT-1 --> <SEQ=100><ACK=300><CTL=FIN,ACK> --> CLOSE-WAIT

    3. FIN-WAIT-2 <-- <SEQ=300><ACK=101><CTL=ACK> <-- CLOSE-WAIT

    4. (Close)
    TIME-WAIT <-- <SEQ=300><ACK=101><CTL=FIN,ACK> <-- LAST-ACK

    5. TIME-WAIT --> <SEQ=101><ACK=301><CTL=ACK> --> CLOSED

    6. (2 MSL)
    CLOSED

    Normal Close Sequence
    ```

    在最后的 4、5 阶段,假如 5 返回给`TCP B`的时候,`1 msl` 过去了,报文过期了;`TCP B` 没有收到,再发一遍,如果设置 `time_wait 状态` 是 `1msl`,那么 `TCP A` 处于`closed`状态,拒收`TCP B`的`FIN 包`,B 无法关闭。

    所以要设置大于 1MSL。

    而 TCP B 重传过来的包,你也要假设他可能需要`1 msl`吧,那么 time_wait 就要`2 msl`的时间来保证此极端情况下,B 能重传成功。
    crab
        5
    crab  
       2020-01-23 23:10:58 +08:00
    一去最大值 msl 一回最大值 msl
    wisej
        6
    wisej  
       2020-01-24 05:39:47 +08:00 via Android
    @jdz 因为如果第四次的 ack 可能丢失,而加上是一去一回,所以是 2msl
    goofool
        7
    goofool  
       2020-01-24 07:37:14 +08:00 via Android
    一个来回时间
    palmers
        8
    palmers  
       2020-01-24 11:38:52 +08:00
    @jdz 你的疑问 在第二条有解释啊, 我猜测你疑惑的是 2MSL 的定义吧?
    RedisMasterNode
        9
    RedisMasterNode  
       2020-01-25 22:49:44 +08:00
    TCPB 向 TCPA 发送 Last ACK,抵达需要 1 个 MSL,抵达后 TCPA 从 FIN_WAIT_2 变成 TIME_WAIT 状态,并且返回 ACK 对 TCPB 进行响应,如果一切正常,那么再过 1 个 MSL 之后就会抵达 B

    假如 TCP A 的这个 ACK 没有抵达 B,那么对于 B 来说,B 发送了一个 Last ACK 出去,处于 CLOSE_WAIT 状态,等待 A 的 ACK 回来,如果 B 在发了 ACK 后过了 2 个 MSL 后没有收到 A 的 ACK,那么就会重新发这个 FIN 报文

    A 等待两个 ACK 的目的是在于防止 ACK 在传输过程中丢失,那么对于 B 来说会在 A 等待 1 个 MSL (这时 B 已经等待了两个 MSL )后重发报文,这个报文过 1MSL 之后内会抵达 A,所以 A 可以在 2 个 MSL 内确认到 B 是否没有接到自己的 ACK
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2621 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 15:50 · PVG 23:50 · LAX 08:50 · JFK 11:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.