time_wait深度详解

什么是time_wait

四次挥手之后,首先发起断开连接的端口会保持time_wait这个状态,这个状态会持续2MSL时间.

首先解释MSL,这个叫最大报文传输时间,这个时间linux系统目前默认值为60秒。这个值存在的唯一意义就是决定time_wait状态维持的时间。它是一个理论值,理论上一个TCP报文从一端到另一端的最大时间肯定是不会超过这个时间长度的。至于这个时间是怎么预估的,RFC里有介绍,大概就是根据IP包的最大跳数,每个包的最大处理时延,最大传输时延等一些列时间的综合。

注意,这个MSL是预估值,无法做到准确定义。尽管在目前的带宽速率以及绝大多数网络环境中,60秒或者30秒甚至更小就完全足够了,但是在一些极端的网络环境中(物理设备故障,带宽巨高,黑客恶意攻击),这个值如果比实际的TCP包到达所用的时间小,那么就可能存在数据异常的问题!所以RFC也建议,一个良好的开发方式就是对收到的数据一定要进行应用层的数据校验

存在的意义

下来再说为什么要保持这个状态2MSL.

  1. 防止最后发送的ack被动关闭端未收到,导致重发fin请求。而这时候如果在主动端有新的连接已经建立,那么新的连接会发送reset消息,从而被迫中断正常的连接。
  2. 防止之前在网络中逗留的TCP包影响新的连接。如果新的连接断开后创建了同样的新的连接,然后这时候旧的包又到达,虽然TCP会根据序列号和滑动窗口来判断包是否有效,但如果刚好旧的包的序列号就在这个范围(旧的序列号会根据发送的数据大小增加,新连接的序列号是随机的,可能刚好两者相同),那么同样会被认定为有效,从而导致数据异常。

根据上面可以看出,第一点在网络繁忙的时候容易出问题。第二点容易出问题的地方就在逗留的包的多少。逗留的包越多(即带宽或网速约快),越容易产生符合相同序列的包,造成错误。所以等待2MSL可以比较好的解决这个问题。至于为啥要2MSL,可以想象一下,假如在关闭之前,主动关闭端刚给被关闭端发送了一个消息,被关闭段收到后要进行ACK确认,这一来一回就是2MSL,如果只等1MSL,那么有可能这个ACK会在MSL之间之外到达,同样会造成错误!所以需要在确定主动关闭方不再发其他包之后,等待2MSL才行。

高性能网络相关

上面提到了数据异常的可能原因是关闭后,重新到达的包的序列号与期待的相同。那么如果两个连接中的两端,会不会存在相同序列号的数据包呢?答案是会,在超高速网络下,是可能。因为序列号的长度是32位,即最大字节数为4GB.只要网速大于4Gb/MSL,则序列号就可能在连接中重复。假设在某个网络中,msl为1秒,带宽为10Gbs,那么在发送途中逗留的字节最多就可以达到10Gb(前提是socket双方约定的滑动窗口也要够大),这个数量会导致tcp包的序列号循环使用而有相同的序列号,如果后面发送的比前面发送的先到,那就完蛋了,出错了。而如果假设msl为10秒,只要带过超过400Mbs就有出错的可能性,当然,在实际情况中,这种情况非常非常少见,一方面是实际包到达的时延会非常小,包要么丢失,要么不到1秒就能到达。另一方面是,当时延很低的情况下,需要带宽非常大,且网络极其繁忙的情况下才会出现序列号重复。所以一般网络环境中可以不用考虑这个问题,只要做好包校验工作,收到异常包断开连接就行(因为之后的其他数据肯定也就跟着错了。)而如果要在时延很高,带宽又很大,网络又很繁忙的极端网络环境中应用tcp的话,可以实现tcp的timestap选项,这个可以选项解决序列号相同的问题,保证包唯一,缺点就是处理会多点步骤,稍稍慢一点点,具体实现不表。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值