1
hfutzj 2020-01-23 22:27:49 +08:00 via Android
仅供参考,有错误欢迎指出
记得有两个原因,一个是保证所有消息生存期过了,二是保证最后发出的断开连接的消息对面能够收到 |
2
palmers 2020-01-23 22:55:00 +08:00
unix 网络编程卷 1 第 38 页摘录有
1. 可靠地实现 TCP 全双工连接的终止。(确保最后的 ACK 能让被关闭方接收); 2. 允许老的重复分节在网络中消逝。( TCP 中是可靠的服务,当数据包丢失会重传,当有数据包迷路的情况下,如果不等待 2MSL 时,当客户端以同样地方式重新和服务建立连接后,上一次迷路的数据包这时可能会到达服务,这时会造成旧包被重新读取)。 |
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 能重传成功。 |
5
crab 2020-01-23 23:10:58 +08:00
一去最大值 msl 一回最大值 msl
|
7
goofool 2020-01-24 07:37:14 +08:00 via Android
一个来回时间
|
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 |