time-wait状态产生的原因

推荐2篇学习TCP的博客文章:
TCP的那些事儿
TCP协议疑难杂症全景解析
可以看相关实际然后和这篇博客结合起来,希望对一起学习的小伙伴有帮助。

TCP的状态机

其实网络上的传输是没有连接,包括TCP也是一样的。而TCP所谓的“连接”,其实只不过是在通讯的双方维护一个“连接状态”,让它看上去好像有连接一样。所以,TCP的状态变换是非常重要的。下面是TCP状态机图片:

1.time_wait状态:

由上面的TCP状态图可知,首先调用close()发起主动关闭的一方,在发送最后一个ACK之后会进入time-wait状态,也就是说该发送方会保持2MSL事件之后才会回到初始状态。MSL值是数据包在网络中的最大生存事件。产生这种结果使得这个TCP连接在2MSL连接等待期间,定义的这个连接的四元数组(local_ip, local_port, remote_ip,remote_port)不能被使用。

2.time_wait状态原因:
1.实现TCP全双工连接的可靠释放

由TCP转换图可知,假设发起主动关闭的一方(client)最后发送的ACK在网络中丢失,由于TCP协议的重传机制,执行被动关闭的一方(server)将会重发其FIN,在该FIN到达client之前,client必须维护这条连接状态,也就是说这条TCP所连接的对应资源(client方的local_ip,local_port)不能被立即释放或重新分配,直到另一方重发的FIN到达 之后,client重发ACK之后,经过2MSL时间周期没有再收到另一方的FIN之后该TCP连接才能恢复到初始的closed状态。如果主动关闭的一方不去维护这个time_wait状态,那么当被关闭一方重发的FIN到达时,主动关闭一方的TCP传输层会用RST包响应对方,这会被对方认为是有错误发生,然而这些事实上只是正常的关闭连接的过程,并非异常。

为了使旧的数据包在网络中因过期而消失

我们先假设TCP协议中不存在TIME_WAIT状态的额限制,再假设当前有一条TCP连接:(local_ip, local_port, remote_ip,remote_port),因为某些原因,我们先关闭,接着很快以相同的四元组建立一条新的连接。本文前面介绍过,TCP连接由四元组唯一标识,因此,在我们假设的情况中,TCP协议栈是无法区分连接的不同的,在它看来,这根本就是同一条连接,中间先释放再连接的过程它也是“感知”不到的。这样就可能发生这样的情况:前一条TCP连接由local peer发送的数据到达remote peer后,会被该remot peer的TCP传输层当做当前TCP连接的正常数据接收并向上传递至应用层(而事实上,在我们假设的场景下,这些旧数据到达remote peer前,旧连接已断开且一条由相同四元组构成的新TCP连接已建立,因此,这些旧数据是不应该被向上传递至应用层的),从而引起数据错乱进而导致各种无法预知的诡异现象。作为一种可靠的传输协议,TCP必须在协议层面考虑并避免这种情况的发生,这正是TIME_WAIT状态存在的第2个原因。

time_wait状态如何避免

首先服务器可以设置SO_REUSEADDR套接字选项来通知内核,如果端口忙,但TCP连接位于TIME_WAIT状态时可以重用端口。在一个非常有用的场景就是,如果你的服务器程序停止后想立即重启,而新的套接字依旧希望使用同一端口,此时SO_REUSEADDR选项就可以避免TIME_WAIT状态。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值