time_wait的快速回收和重用

本文探讨了TCP连接中的time_wait状态,包括其产生原因、作用以及可能导致的TIME_WAIT连接过多问题。当系统出现大量TIME_WAIT连接时,可能导致无法建立新的TCP连接。解决方案包括调整系统配置如增大tcp_max_tw_buckets,开启tcp_tw_recycle和tcp_tw_reuse,以及将短连接改为长连接等。
摘要由CSDN通过智能技术生成

问题现象:PC与工控机之间通信,工控机发送SYN,PC一直回复FIN或者RST

问题解释:

1. time_wait产生的原因及作用

下面我们先来简单回顾一下TCP连接关闭动作:

tcp-close

在Linux环境下我们可以如下的方式来统计TCP连接的情况:

# netstat -nat | awk '/^tcp/ {++S[$NF]} END{for(a in S) print S[a], "\t", a}'
1        LAST_ACK
57       LISTEN
113953   ESTABLISHED
5        FIN_WAIT1
16       FIN_WAIT2
2        SYN_SENT
559      TIME_WAIT

上面我们看到,大部分的连接处于ESTABLISHED状态,目前比较少的处于TIME_WAIT状态,当前机器看起来还算是正常。

1) time_wait状态如何产生?

通过上面的变迁图,首先调用close()发起主动关闭的一方,在发送最后一个ACK之后会进入time_wait的状态,也就是说该发送方会保持2MSL时间之后才会回到初始状态。MSL指的是数据包在网络中的最大生存时间。在这样一个2MSL长的等待时间内,定义这个连接的四元组(客户端IP/Port,服务端IP/Port)不能被使用。

2)time_wait状态产生的原因

  • 为实现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包响应对方,这会被对方认为是有错误发生,然而这事实上这只是正常的关闭连接过程,并非异常。

确保被动关闭方收到ACK,连接正常关闭,且不因被动关闭方重传 FIN 影响下一个新连接。
  • 为使旧的数据包在网络因过期而消失

为说明这个问题,我们先假设TCP协议中不存在TIME_WAIT状态的限制,再假设当前有一条TCP连接(local_ip/local_port, remote_ip/remote_port),因某些原因,我们先关闭,接着很快以相同的四元组建立一条新连接。本文前面介绍过,TCP连接由四元组唯一标识,因此,在我们假设的情况中,TCP协议栈是无法区分前后两条TCP连接的不同的,在它看来,这根本就是同一条连接,中间先释放再建立连接的过程对其来说是感知不到的。这样就可能发生这样的情况:前一条TCP连接由lo

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值