存在目的
TIME_WAIT 状态也称为 2MSL 等待状态。在该状态中,TCP 将会等待两倍于最大段生存期(Maximum Segment Lifetime,MSL)的时间。
在 RFC 9293 中对 TIME_WAIT 状态有如下描述:
TIME-WAIT - represents waiting for enough time to pass to be sure the remote TCP peer received the acknowledgment of its connection termination request and to avoid new connections being impacted by delayed segments from previous connections.
TIME_WAIT 状态存在的理由总结如下:
- 可靠地实现 TCP 全双工连接的终止
- 允许老的重复数据在网络中消逝
可靠地实现 TCP 全双工连接的终止
我们要等待足够的时间,以便让被动关闭方能够接收到最后的 ACK。
假如主动关闭方最后一个 ACK 丢失了,被动关闭方没收到回应会重传 FIN,此时主动关闭方收到后得知自己的 ACK 丢失了,于是重新发送最后的 ACK。
要是没有 TIME_WAIT 状态,主动关闭方在发送最后一个 ACK 后直接进入 CLOSE 状态,在收到被动关闭方重传的 FIN 后,它将响应一个 RST,该报文被被动关闭方解释成一个错误,随后关闭连接。TCP 是一个可靠的传输控制协议,它必须正确处理连接终止发送的 4 个报文中任何一个丢失的情况。
允许老的重复数据在网络中消逝
假设我们关闭了一个 TCP 连接,随后又用相同的 IP 地址和端口号建立另一个连接。把刚才关闭的叫做历史连接,刚创建的叫做新连接。
TCP 必须防止来自某个历史连接中的数据出现,从而被误认为是新连接中的数据。为做到这一点,TCP 禁止给处于 TIME_WAIT 状态的连接创建新连接。因为 TIME_WAIT 状态将持续 2MSL,这足以上某个方向上的数据被丢弃,另一个方向上的应答也最多存活 MSL 秒后被丢弃。
2MSL 的思考
用主动关闭方最后的 ACK 和被动关闭方的 FIN 来理解 2MSL。
主动关闭方在发出最后的 ACK 时开始计时,等待 2MSL,在收到重传的 FIN 后重新计时。
首先,主动关闭方 TIME_WAIT 时间必须维持 MSL 以上,因为它可能发送了多个 ACK,它要保证自己发送的多余的 ACK 在网络中被丢弃。然后,假如被动关闭方在收到 ACK 前又重传了 FIN,这样的话还得再多等一个 MSL 时间。
这个地方还是感觉有些困惑。
参考资料
- 《UNIX网络编程卷1:套接字联网API(第3版)》
- 《TCPIP详解 卷1:协议(原书第2版)》
- RFC 9293
- 小林coding 为什么需要-time-wait-状态
- 为什么tcp的TIME_WAIT状态要维持2MSL