TCP套接字服务器偶尔会建立CLOSE_WAIT,直到无法操作

Kie*_*ton 4 c# sockets crash performance wireshark

希望有人可以帮助我们,因为我们已达到调查的范围!

我们有一个用C#编写的简单异步套接字服务器,它接受来自ASP.NET Web应用程序的连接,发送消息,执行一些处理(通常是对数据库,但也是其他系统),然后将响应发送回客户端.客户负责关闭连接.

我们一直遇到这样的问题:如果系统长时间处于高负荷状态(通常是几天),CLOSE_WAIT套接字会在服务器框(netstat -a)上堆积到一定程度,以至于进程不接受任何进一步的连接.那时我们必须反弹这个过程然后再次运行.

我们已经尝试运行ASP.NET应用程序的一些负载测试来尝试复制问题(因为从代码中推断出某些问题是不可能的).我们认为我们已经对此进行了管理,并最终得到了一个问题的WireShark 数据包跟踪,该问题在套接字服务器的日志中表现为SocketException:

System.Net.Sockets.SocketException:System.Net.Sockets.Socket.BeginSend(Byte []缓冲区,Int32偏移量,Int32大小,SocketFlags socketFlags,AsyncCallback回调,对象状态)中的远程主机强制关闭现有连接

我试图从数据包跟踪中重现问题,作为直接与套接字服务器通信的单线程进程(使用与ASP.NET应用程序相同的代码)并且无法进行.

有没有人对下一步的事情有任何建议,检查或明显我们可能做错了什么?

Len*_*ate 5

如果您的服务器正在累积CLOSE_WAIT套接字,则在连接完成时它不会关闭其套接字.如果你看一下Chris'帖子的评论中的状态图,你会看到一旦套接字关闭并且已经发送CLOSE_WAIT过渡.LAST_ACKFIN

你说由于异步性质,确定在哪里这样做很复杂?这应该不是问题,如果来自recv的回调返回0字节,则应关闭套接字(假设您的客户端关闭其连接端后没有其他任何操作).如果您确实需要担心继续发送,请在此处执行关机(recv)并记下您的客户端已关闭,一旦您完成发送关闭(发送)和关闭.

你可能会在read的回调中发出一个新的读取,返回0表示客户端已经关闭,这可能会导致你出现问题?


yog*_*man 5

看看图表

http://en.wikipedia.org/wiki/File:Tcp_state_diagram_fixed.svg

您的客户端通过调用close()来关闭连接,它将FIN发送到服务器套接字,服务器套接字确认FIN并且其状态现在已更改为CLOSE_WAIT,并保持该状态,除非服务器在该套接字上发出close()调用.

您的服务器程序需要检测客户端是否已中止连接,然后立即关闭()它以释放端口.怎么样?请参阅read().在读取文件结尾(意味着收到FIN)时,返回零.