等待是什么意思?(TCP连接状态CLOSE_WAIT和TIME_WAIT的详细分析)
admin
2023-10-29 03:00:52

一、TCP连接状态简介

TCP协议规定,对于已建立的连接,网络两端都要挥动四次才能成功断开连接。如果缺少其中一个步骤,连接将处于假死状态,连接本身占用的资源不会被释放。

网络服务器程序要同时管理大量的连接,所以需要保证无用的连接完全断开,否则大量的死连接会浪费大量的服务器资源。在许多TCP国家中,有两个最值得注意:CLOSE_WAIT和TIME_WAIT.

如果服务器出现异常,80%或90%是以下两种情况:

服务器维护大量的TIME_WAIT状态;服务器维护大量的CLOSE_WAIT状态;因为linux分配给一个用户的文件句柄是有限的,如果一直保持TIME_WAIT和CLOSE_WAIT两种状态,就意味着相应数量的通道一直被占用,它们& quot占着厕所不努力& quot。一旦达到句子句柄的最大数量,就无法处理新的请求,随之而来的是大量的TooManyOpenFiles异常,tomcat就会崩溃。

在服务器的日常维护中,经常会用到以下命令:

netstat-n|awk'/^tcp/{ s[$ nf]} end { for(ains)printa,S[a]} '

例如,它显示以下信息:

时间_等待814

关闭_等待1

FIN_WAIT11

编制634

SYN_RECV2

LAST_ACK1

常用的三种状态是:ESTABLISHED表示通信,TIME_WAIT表示主动关机,CLOSE_WAIT表示被动关机。

二、TCP连接状态详解

每个州代表什么?请看下面的介绍。

1.收听状态

FTP服务启动后,首先处于侦听状态。

2.既定地位

建立是指建立连接。表示两台机器正在通信。

3、关闭_等待

当对方主动关闭连接或者网络异常导致连接中断时,我们的状态会变为CLOSE_WAIT,我们会调用CLOSE()来正确关闭连接。

4、时间_等待

我们主动调用close()断开连接,收到对方确认后状态变为TIME_WAIT。TCP协议规定TIME_WAIT状态将持续2MSL(即分段最大生存期的两倍),以保证旧的连接状态不会影响新的连接。TIME_WAIT状态下连接所占用的资源不会被内核释放,所以作为服务器,如果可能的话尽量不要主动断开,以减少TIME_WAIT状态造成的资源浪费。

目前有一个避免浪费TIME_WAIT资源的方法,就是关闭socket的LINGER选项。但是,TCP协议不推荐这种做法,在某些情况下,这种操作可能会带来错误。

5.同步状态

SYN_SENT状态表示连接请求。当你想访问其他电脑的服务时,你必须先向端口发送一个同步信号。此时状态为SYN_SENT,如果连接成功,将变为建立。此时,SYN_SENT状态非常短。但是,如果你发现SYN_SENT非常丰富,并且正在发送到不同的机器上,那么你的机器可能感染了冲击波或冲击波之类的病毒。这种病毒为了感染其他电脑,要对其他电脑进行扫描,并且在扫描的过程中,向每一台被扫描的电脑发出同步请求,这也是很多SYN_SENT出现的原因。

三、TCP连接的释放(四次挥手)

数据传输后,双方可以释放连接。一开始客户端和服务器都是建立状态,然后客户端主动关机,服务器被动关机。

1.客户端进程发送连接释放消息并停止发送数据。释放数据报文的头,FIN=1,其序列号为seq=u(等于之前已经发送的数据最后一个字节的序列号加1)。此时,客户端进入FIN-WAIT-1状态。TCP规定,即使FIN段不携带数据,它也会消耗一个序列号。

2.服务器收到连接释放消息,发出ACK=1,ack=u 1的确认消息,自带序列号SEQ=V,此时服务器进入关闭等待状态。当TCP服务器通知更高的应用程序进程时,从客户端到服务器的方向被释放。此时处于半封闭状态,即客户端没有数据发送,但如果服务器发送数据,客户端还是要接受。这种状态将持续一段时间,即整个关闭等待状态的持续时间。

3.客户端收到服务器的确认请求后,此时客户端进入FIN-WAIT-2状态,等待服务器发送连接释放消息(在此之前,需要接受服务器发送的最后一个数据)。

4.服务器发送完最后一个数据后,向客户端发送连接释放消息,FIN=1,ack=u 1。因为是半封闭状态,服务器很可能又发了一些数据,假设此时的序列号是seq=w,此时服务器进入LAST-ACK状态,等待客户端的。

确认。

5.客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2*MSL(最长报文段寿命,maxsegmentlifetime)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

6.服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些


四、服务器保持了大量TIME_WAIT状态

这种情况比较常见,一些爬虫服务器或者WEB服务器(如果网管在安装的时候没有做内核参数优化的话)上经常会遇到这个问题,这个问题是怎么产生的呢?

从上面的示意图可以看得出来,TIME_WAIT是主动关闭连接的一方保持的状态,对于爬虫服务器来说它本身就是客户端,在完成一个爬取任务之后,它就会发起主动关闭连接,从而进入TIME_WAIT的状态。然后在保持这个状态2MSL(maxsegmentlifetime)时间之后,彻底关闭回收资源。


为什么要这么做?明明就已经主动关闭连接了为啥还要保持资源一段时间呢?

这个是TCP/IP的设计者规定的,主要出于以下两个方面的考虑:

1.防止上一次连接中的包,迷路后重新出现,影响新连接(经过2MSL,上一次连接中所有的重复包都会消失)。

2.可靠的关闭TCP连接。在主动关闭方发送的最后一个ack(fin),有可能丢失,这时被动方会重新发fin,如果这时主动方处于CLOSED状态,就会响应rst而不是ack。所以主动方要处于TIME_WAIT状态,而不能是CLOSED。另外这么设计TIME_WAIT会定时的回收资源,并不会占用很大资源的,除非短时间内接受大量请求或者受到攻击。


五、服务器保持了大量CLOSE_WAIT状态

TIME_WAIT状态可以通过优化服务器参数得到解决,因为发生TIME_WAIT的情况是服务器自己可控的,要么就是对方连接的异常,要么就是自己没有迅速回收资源,总之不是由于自己程序错误导致的。

但是CLOSE_WAIT就不一样了,从上面的图可以看出来,如果一直保持在CLOSE_WAIT状态,那么只有一种情况,就是在对方关闭连接之后服务器程序自己没有进一步发出ack信号。换句话说,就是在对方连接关闭之后,程序里没有检测到,或者程序压根就忘记了这个时候需要关闭连接,于是这个资源就一直被程序占着。


执行如下命令:

netstat-n|awk'/^tcp/{++S[$NF]}END{for(ainS)printa,S[a]}'

发现CLOSE_WAIT的数量始终在400以上,一直没降过。

个人觉得这种情况,通过服务器内核参数也没办法解决,服务器对于程序抢占的资源没有主动回收的权利,除非终止程序运行。


如果你使用的是HttpClient并且你遇到了大量CLOSE_WAIT的情况,那么这篇日志也许对你有用:

HttpClient连接池抛出大量ConnectionPoolTimeoutException:Timeoutwaitingforconnection异常排查

http://blog.csdn.net/shootyou/article/details/6615051


在那边日志里头我举了个场景,来说明CLOSE_WAIT和TIME_WAIT的区别,这里重新描述一下:

服务器A是一台爬虫服务器,它使用简单的HttpClient去请求资源服务器B上面的apache获取文件资源,正常情况下,如果请求成功,那么在抓取完资源后,服务器A会主动发出关闭连接的请求,这个时候就是主动关闭连接,服务器A的连接状态我们可以看到是TIME_WAIT。

如果一旦发生异常呢?假设请求的资源服务器B上并不存在,那么这个时候就会由服务器B发出关闭连接的请求,服务器A就是被动的关闭了连接,如果服务器A被动关闭连接之后程序员忘了让HttpClient释放连接,那就会造成CLOSE_WAIT的状态了。

所以如果将大量CLOSE_WAIT的解决办法总结为一句话那就是:查代码。因为问题出在服务器程序里头。

相关内容

热门资讯

金花创建房间/微信金花房卡怎么... 1.微信渠道:(荣耀联盟)大厅介绍:咨询房/卡添加微信:88355042 2.微信游戏中心:打开微...
金花房间卡/金花房卡如何购买/... 金花房间卡/金花房卡如何购买/新超圣金花房卡正版如何购买新超圣是一款非常受欢迎的游戏,咨询房/卡添加...
牛牛创建房间/金花房卡批发/神... 微信游戏中心:神牛大厅房卡在哪里买打开微信,添加客服【88355042】,进入游戏中心或相关小程序,...
链接牛牛/牛牛房卡游戏代理/鸿... 鸿运大厅房卡更多详情添加微:33549083、 2、在商城页面中选择房卡选项。 3、根...
科技实测!牛牛房卡怎么获得/乐... 微信游戏中心:乐酷大厅房卡在哪里买打开微信,添加客服【88355042】,进入游戏中心或相关小程序,...