生成原因:
如果我们的Client程序处于CLOSE_WAIT状态的话,说明Socket是被动关闭的.
因为如果是Server端主动断掉当前连接的话,那么双方关闭这个TCP连接共需要四个packet:
Server ---> FIN ---> Client
Server <--- ACK <--- Client
这时候Server端处于FIN_WAIT_2状态,也就是传说中的半连接状态;而我们的程序处于CLOSE_WAIT状态。
Server <--- FIN <--- Client
这时Client发送FIN给Server,Client就置为LAST_ACK状态。
Server ---> ACK ---> Client
Server回应了ACK,那么Client的Socket才会真正置为CLOSED状态
既然如此,我们的程序处于CLOSE_WAIT状态,而不是LAST_ACK状态,说明还没有发FIN给Server,那么可能是在关闭连接之前还有许多数据要发送或者其他事要做,导致没有发FIN
原因分析:
1. 难道Client根本不知道自己收到了FIN包
当Server调用closesocket的时候,Client正在read中,这时候有可能对方发送的FIN包我没有收到,而是由TCP代回了一个ACK包,所以我这边套接字进入CLOSE_WAIT状态.但是我在read的时候,会判断返回值是否已出错,是错误值的话就主动closesocket,这样防止没有接收到FIN包。
2. 为什么大量连接都处于CLOSE_WAIT,难道服务器端总是主动断开连接?
有一种可能就是没有重用本地地址和端口,一个端口不行,总是换另外一个来用,导致大量的端口进入CLOSE_WAIT状态。也许我们无法避免被冻结在CLOSE_WAIT状态永远不出现,但起码可以保证不会占用新的端口。加上类似的代码保证重用
sc.setReuseAddress(true);
3. 网上查到强行关闭的问题
socket.setSoLinger(boolean on,int linger)
设置SO_LINGER为0,CloseSocket的时候,不论是否有排队数据未发送或未被确认。这种关闭方式称为“强行关闭”,因为Socket的虚电路立即被reset,尚未发出的所有数据都会丢失。在远端的read都会抛出IOException.
4.最终的问题
根据分析得到,只要Client端主动调用了closeSocket,一定会发送FIN包,并改变自己的状态。因此debug程序代码,发现问题的真正所在。因为系统关闭socket是异步调用,在关闭事件执行之前,有异常抛出,导致异步EventHandlerThread死掉,然后事件被丢弃。想办法fix了这个问题,让
sc.close();
被真正执行了,一切OK.
总结:
当发起主动关闭的左边这方发送一个FIN过去后,右边被动关闭的这方要回应一个ACK,这个ACK是TCP回应的,而不是应用程序发送的,此时,被动关闭的一方就处于CLOSE_WAIT状态了。如果此时被动关闭的这一方不再继续调用closesocket,那么他就不会发送接下来的FIN,导致自己老是处于CLOSE_WAIT。这个时候如果去做read或者write,就会抛出IOException,必须成功调用closesocket,才会发送一个FIN给主动关闭的这一方,同时也使得自己的状态变迁为LAST_ACK。
分享到:
相关推荐
CLOSE_WAIT网络连接无法释放问题解决 CLOSE_WAIT是一个常见的TCP连接状态,指的是服务器端的连接在客户端关闭后还未释放的情况。这种情况经常出现于客户端主动断开连接,但服务器端没有正确关闭连接的情况下。这种...
在 TCP 连接中,客户端和服务器端都可以处于不同的状态,例如 ESTABLISHED、CLOSE_WAIT、FIN_WAIT_1、FIN_WAIT_2、TIME_WAIT 等 trạng thái。 CLOSE_WAIT 状态是 TCP 连接中的一种状态,它表示服务器端已经收到了...
文件"close_wait_0306.chm"和"close_wait_0306"可能是关于这个问题的文档或日志文件,它们可能包含了更详细的错误信息、堆栈跟踪或连接状态的历史记录。CHM文件是Microsoft的帮助文件格式,通常包含软件的文档或技术...
TCP连接有多种状态,包括LISTEN、SYN_SENT、SYN_RECEIVED、ESTABLISHED、CLOSE_WAIT、FIN_WAIT_1、FIN_WAIT_2、TIME_WAIT等。每个状态都代表了连接的不同生命周期阶段。Close_Wait是服务器端接收到客户端的FIN( ...
在TCP/IP协议栈中,CLOSE_WAIT是一个非常关键的连接状态,它涉及到客户端和服务器之间的通信。这个状态在处理网络连接时可能出现的问题时尤其重要。本文将深入探讨CLOSE_WAIT错误的含义、原因以及如何解决。 首先,...
在TCP/IP协议栈中,"Close_Wait"是一种连接状态,表示一个方向的连接已经关闭,而另一个方向仍然保持开放,等待应用层关闭。当服务器接收到客户端的FIN(结束)标志,它会进入Close_Wait状态,表示服务器已经接收到...
但是,由于TCP连接是全双⼯的...CLOSE_WAIT则可能指示应用程序或系统的问题。解决这些问题需要深入理解TCP连接生命周期,优化代码、调整系统参数以及合理使用连接池。在进行这些操作时,应谨慎行事,以免引入新的问题。
如果对方在第三次握手的时候出问题,例如发 FIN 包的时候,不知道什么原因丢了这个包,客户端会一直处在 FIN_WAIT_2 状态,服务器端则处在 CLOSE_WAIT 状态。如果这种情况持续很长时间,系统可能会崩溃。 问题分析 ...
在处理TCP连接时,需要特别关注close()函数的使用,因为它可能直接影响到TIME_WAIT状态的处理。 `c-means`可能是指一种基于C语言的聚类算法,虽然在这个上下文中没有直接关联,但如果你正在学习C语言编程,并试图将...
tcp4 0 0 127.0.0.1.50937 127.0.0.1.8383 CLOSE_WAIT 这次我们了解到的是,只有在应用程序显式调用close或终止应用程序时,才可以接收等待CLOSE_WAIT的关闭。 因此,如果您在这种CLOSE_WAIT状态下无限期地等待,...
在实际应用中,结合这两个文件,IT管理员可以定期检查服务器的TCP连接情况,例如检测是否有大量半开连接(SYN_SENT或SYN_RECV)、是否存在长时间未关闭的连接(FIN_WAIT或CLOSE_WAIT),或者是否因为连接资源耗尽而...
例如,可以通过修改 tcp_keepalive_*系列参数来解决 CLOSE_WAIT 状态的问题。此外,还可以通过修改 inet_peer_gc_maxtime、inet_peer_gc_mintime 等参数来调整 INET peer storage 的大小和时间间隔。 Linux 下 TCP ...
标题 "tomcat-timewait-closewait.zip" 暗示了这个压缩包可能包含与Tomcat服务器在处理TCP连接时遇到的“Time_wait”和“Close_wait”状态相关的问题和解决方案。这两个术语是TCP/IP协议栈中的关键概念,尤其在高...
源码分析可能涉及理解TCP的状态机,如CLOSED、LISTEN、SYN_SENT、SYN_RCVD、ESTABLISHED、FIN_WAIT_1、FIN_WAIT_2、CLOSE_WAIT、CLOSING、LAST_ACK、TIME_WAIT等状态及其转换。同时,还会涉及IP头部的解析,以及错误...
当一个TCP连接处于CLOSE_WAIT状态时,这意味着服务器已经接收到客户端发送的FIN( Finish)报文,表示客户端想要关闭连接。然而,服务器还没有准备好关闭连接,可能是因为它还有未发送的数据或者需要执行某些清理...
它可以由多个状态转移到达,包括 FIN_WAIT_2、CLOSING 和 FIN_WAIT_1 状态。TIME_WAIT 状态的存在是为了确保 TCP 连接的可靠终止和允许老的重复分节在网络中消逝。 了解 TCP 连接状态是非常重要的,因为它可以帮助...
5. FIN_WAIT1:主动关闭(active close)端应用程序调用 close,于是其 TCP发出 FIN 请求主动关闭连接,之后进入 FIN_WAIT1 状态。 6. CLOSE_WAIT:被动关闭(passive close)端 TCP 接到 FIN。 7. FIN_WAIT2:主动...