http://apps.hi.baidu.com/share/detail/21679535
Socket中的TIME_WAIT状态
在高并发短连接的server端,当server处理完client的请求后立刻closesocket此时会出现time_wait状态然后如果client再并发2000个连接,此时部分连接就连接不上了,用linger强制关闭可以解决此问题,但是linger会导致数据丢失,linger值为0时是强制关闭,无论并发多少多能正常连接上,如果非0会发生部分连接不上的情况!(
可调用setsockopt设置套接字的linger延时标志,同时将延时时间设置为0。)
TCP/IP的RFC文档。
TIME_WAIT是TCP连接断开时必定会出现的状态。是无法避免掉的,这是TCP协议实现的一部分。在WINDOWS下,可以修改注册表让这个时间变短一些.time_wait的时间为2msl,默认为4min.你可以通过改变这个变量:TcpTimedWaitDelay
把它缩短到30s.
TCP要保证在所有可能的情况下使得所有的数据都能够被投递。当你关闭一个socket时,主动关闭一端的socket将进入TIME_WAIT状态,而被动关闭一方则转入CLOSED状态,这的确能够保证所有的数据都被传输。当一个socket关闭的时候,是通过两端互发信息的四次握手过程完成的,当一端调用close()时,就说明本端没有数据再要发送了。这好似看来在握手完成以后,socket就都应该处于关闭CLOSED状态了。但这有两个问题,首先,我们没有任何机制保证最后的一个ACK能够正常传输,第二,网络上仍然有可能有残余的数据包(wandering
duplicates),我们也必须能够正常处理。
通过正确的状态机,我们知道双方的关闭过程如下
图
假设最后一个ACK丢失了,服务器会重发它发送的最后一个FIN,所以客户端必须维持一个状态信息,以便能够重发ACK;如果不维持这种状态,客户端在接收到FIN后将会响应一个RST,服务器端接收到RST后会认为这是一个错误。如果TCP协议能够正常完成必要的操作而终止双方的数据流传输,就必须完全正确的传输四次握手的四个节,不能有任何的丢失。这就是为什么socket在关闭后,仍然处于
TIME_WAIT状态,因为他要等待以便重发ACK。
如果目前连接的通信双方都已经调用了close(),假定双方都到达CLOSED状态,而没有TIME_WAIT状态时,就会出现如下的情况。现在有一个新的连接被建立起来,使用的IP地址与端口与先前的完全相同,后建立的连接又称作是原先连接的一个化身。还假定原先的连接中有数据报残存于网络之中,这样新的连接收到的数据报中有可能是先前连接的数据报。为了防止这一点,TCP不允许从处于TIME_WAIT状态的socket建立一个连接。处于TIME_WAIT状态的socket在等待两倍的MSL时间以后(之所以是两倍的MSL,是由于MSL是一个数据报在网络中单向发出到认定丢失的时间,一个数据报有可能在发送图中或是其响应过程中成为残余数据报,确认一个数据报及其响应的丢弃的需要两倍的MSL),将会转变为CLOSED状态。这就意味着,一个成功建立的连接,必然使得先前网络中残余的数据报都丢失了。
由于TIME_WAIT状态所带来的相关问题,我们可以通过设置SO_LINGER标志来避免socket进入TIME_WAIT状态,这可以通过发送RST而取代正常的TCP四次握手的终止方式。但这并不是一个很好的主意,TIME_WAIT对于我们来说往往是有利的。
客户端与服务器端建立TCP/IP连接后关闭SOCKET后,服务器端连接的端口状态为TIME_WAIT,是不是所有执行主动关闭的socket都会进入TIME_WAIT状态呢?有没有什么情况使主动关闭的socket直接进入CLOSED状态呢?
主动关闭的一方在发送最后一个 ack 后,就会进入 TIME_WAIT 状态 停留2MSL(max segment
lifetime)时间,这个是TCP/IP必不可少的,也就是“解决”不了的。
也就是TCP/IP设计者本来是这么设计的
主要有两个原因
1。防止上一次连接中的包,迷路后重新出现,影响新连接
(经过2MSL,上一次连接中所有的重复包都会消失)
2。可靠的关闭TCP连接
在主动关闭方发送的最后一个 ack(fin)
,有可能丢失,这时被动方会重新发
fin, 如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。所以
主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。
TIME_WAIT
并不会占用很大资源的,除非受到攻击。
还有,如果一方 send 或 recv 超时,就会直接进入 CLOSED
状态
分享到:
相关推荐
在IT领域,尤其是在服务器运维与数据库管理中,遇到“大量TIME_WAIT”状态的问题并不罕见,尤其是在高并发场景下,如MySQL服务器。本文将深入解析如何有效解决MySQL出现大量TIME_WAIT状态的问题,通过调整系统内核...
TIME_WAIT是一种TCP连接的状态,当一个TCP连接被主动关闭时,客户端会进入TIME_WAIT状态,目的是确保任何可能在网络中滞留的数据包能够被正确处理,避免这些数据包在未来的新连接中被误解释。然而,在高并发场景下,...
当一个 TCP 连接关闭时,服务器端会在 TIME_WAIT 状态下等待一段时间,以确保所有的数据包都已经被客户端收到。在这个状态下,服务器端会等待两个最大段生命周期(Maximum Segment Lifetime,MSL)的时间,以确保...
在 TCP 连接中,客户端和服务器端都可以处于不同的状态,例如 ESTABLISHED、CLOSE_WAIT、FIN_WAIT_1、FIN_WAIT_2、TIME_WAIT 等 trạng thái。 CLOSE_WAIT 状态是 TCP 连接中的一种状态,它表示服务器端已经收到了...
在TIME_WAIT状态中,客户端必须维持状态信息,以便在最后的ACK丢失时重发最终的ACK,这样才能确保TCP全双工连接的正常终止。如果不维持这个状态信息,那么客户端将响应RST分节,服务器将此分节解释成一个错误。 ...
本文讨论了在线上环境中,服务端长连接和客户端短连接配置不当导致Nginx服务器产生大量“TIME_WAIT”状态线程的问题,同时提供了问题的分析和解决方法。本文主要涉及的网络编程知识点包括长连接与短连接的定义和区别...
使用netstat -na命令可以查看当前的TCP连接状态,包括LISTEN、ESTABLISHED、TIME_WAIT等状态。在这个例子中,使用netstat -na命令可以发现服务器端的连接状态为CLOSE_WAIT,这就表明服务器端的连接尚未释放。 通过...
当TCP连接的一端(通常是客户端)发送了FIN(结束)报文并收到对方的ACK(确认)后,该连接就会进入TIME_WAIT状态。此状态的主要目的是确保所有的数据都已经被接收,并防止旧的连接与新连接混淆。 TIME_WAIT状态的...
- 客户端:大量time_wait会占用内存,且可能导致端口耗尽,超过`ip_local_port_range`设定范围后无法建立新的连接。 - 服务端:不会面临端口耗尽的问题,但同样会有内存资源浪费。 6. 实际场景验证 在Cobar测试中,...
TCP TIME_WAIT状态是TCP连接生命周期中的一个重要阶段,它发生在主动关闭连接的一方(通常称为客户端)在连接关闭后等待一段时间,以确保所有在网络中可能残留的数据片段都被接收并确认。这个阶段的存在是为了避免旧...
在TCP/IP协议栈中,CLOSE_WAIT是一个非常关键的连接状态,它涉及到客户端和服务器之间的通信。这个状态在处理网络连接时可能出现的问题时尤其重要。本文将深入探讨CLOSE_WAIT错误的含义、原因以及如何解决。 首先,...
文件"close_wait_0306.chm"和"close_wait_0306"可能是关于这个问题的文档或日志文件,它们可能包含了更详细的错误信息、堆栈跟踪或连接状态的历史记录。CHM文件是Microsoft的帮助文件格式,通常包含软件的文档或技术...
4. 关闭 TIME_WAIT 连接:使用 netstat -ant | grep TIME_WAIT | awk '{print $2}' | xargs kill -9 命令可以关闭 TIME_WAIT 连接。 网络连接状态详解: 网络连接状态可以分为 12 种可能的状态,前面 11 种是按照 ...
TIME_WAIT状态是TCP连接生命周期中的一个阶段,它在客户端主动关闭连接后出现,服务器端的端口在一段时间内保持此状态,以便处理可能在网络中漂浮的旧数据包。这种状态对于确保连接的可靠关闭至关重要,但过多的TIME...
tcp连接是网络编程中最基础的概念,基于不同的使用场景,我们一般区分为“长连接”和“短...长短连接的优点和缺点这里就不详细展开了,有心的同学直接去google查询,本文主要关注如何解决tcp短连接的TIME_WAIT问题。
如果大量的 Time_wait ...使用 TCP Keepalive:TCP Keepalive 可以在服务器端和客户端之间建立持久连接,避免连接断开后导致的 TIME_WAIT 状态。 使用传输层网关:传输层网关可以代替服务器端和客户端之间的直接连接,