Java:吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题( 八 )
为什么 TIME_WAIT 等待的时间是 2MSL?
MSL 是 Maximum Segment Lifetime , 报文最大生存时间 , 它是任何报文在网络上存在的最长时间 , 超过这个时间报文将被丢弃 。 因为 TCP 报文基于是 IP 协议的 , 而 IP 头中有一个 TTL 字段 , 是 IP 数据报可以经过的最大路由数 , 每经过一个处理他的路由器此值就减 1 , 当此值为 0 则数据报将被丢弃 , 同时发送 ICMP 报文通知源主机 。
MSL 与 TTL 的区别:MSL 的单位是时间 , 而 TTL 是经过路由跳数 。 所以 MSL 应该要大于等于 TTL 消耗为 0 的时间 , 以确保报文已被自然消亡 。
TIME_WAIT 等待 2 倍的 MSL , 比较合理的解释是:网络中可能存在来自发送方的数据包 , 当这些发送方的数据包被接收方处理后又会向对方发送响应 , 所以一来一回需要等待 2 倍的时间 。
比如 , 如果被动关闭方没有收到断开连接的最后的 ACK 报文 , 就会触发超时重发 Fin 报文 , 另一方接收到 FIN 后 , 会重发 ACK 给被动关闭方 ,一来一去正好 2 个 MSL 。
2MSL 的时间是从客户端接收到 FIN 后发送 ACK 开始计时的 。 如果在 TIME-WAIT 时间内 , 因为客户端的 ACK 没有传输到服务端 , 客户端又接收到了服务端重发的 FIN 报文 , 那么 2MSL 时间将重新计时 。
在 Linux 系统里 2MSL 默认是 60 秒 , 那么一个 MSL 也就是 30 秒 。 Linux 系统停留在 TIME_WAIT 的时间为固定的 60 秒 。
其定义在 Linux 内核代码里的名称为 TCP_TIMEWAIT_LEN:
#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT state, about 60 seconds */
如果要修改 TIME_WAIT 的时间长度 , 只能修改 Linux 内核代码里 TCP_TIMEWAIT_LEN 的值 , 并重新编译 Linux 内核 。
为什么需要 TIME_WAIT 状态?
主动发起关闭连接的一方 , 才会有 TIME-WAIT 状态 。
需要 TIME-WAIT 状态 , 主要是两个原因:
- 防止具有相同「四元组」的「旧」数据包被收到;
- 保证「被动关闭连接」的一方能被正确的关闭 , 即保证最后的 ACK 能让被动关闭方接收 , 从而帮助其正常关闭;
假设 TIME-WAIT 没有等待时间或时间过短 , 被延迟的数据包抵达后会发生什么呢?
本文插图
接收到历史数据的异常
- 如上图黄色框框服务端在关闭连接之前发送的 SEQ = 301 报文 , 被网络延迟了 。
- 这时有相同端口的 TCP 连接被复用后 , 被延迟的 SEQ = 301 抵达了客户端 , 那么客户端是有可能正常接收这个过期的报文 , 这就会产生数据错乱等严重的问题 。
原因二:保证连接正确关闭
在 RFC 793 指出 TIME-WAIT 另一个重要的作用是:
TIME-WAIT - represents waiting for enough time to pass to be sure the remote TCP received the acknowledgment of its connection termination request.
推荐阅读
- 『Java』java数据结构系列——什么是数据结构
- 『Java』马云:成功人跟普通人差不多,但这三点我一定要分享给所有年轻人
- 小谢娱乐哦引来广大网友狂点赞,直呼炸天,程序员用Java实现扫雷小游戏
- 「客户端」学习网络编程,不了解TCP协议?难怪面试被刷下去,还不来学习!
- 体坛焦点全场吊打对手,上港苦主独造三球,4-0狂胜!申花亚冠劲敌踢疯了
- #Java#java线程到底有多少种状态?
- 【皇室战争】皇室战争:狂暴模式被吊打?学会这套卡组,轻松连胜拿奖励
- Muster电竞单挑省级马超惨遭吊打,网友:真香,国服瑶妹打脸梦泪失败
- 星空游戏精选小羊火龙溢出严重,法师吊打满配物理队?明日方舟高台输出太强
- #智能手表#1、初识java-1
