希望有人能帮助我们,因为我们要尽可能的调查可以去达到!

我们已经得到了写在从ASP.NET web应用程序接受连接C#简单异步套接字服务器,被发送的消息,(针对DB但其他系统通常太)执行一些处理,然后发送回一个响应到客户端。客户端负责关闭连接的。

我们一直有,如果系统负载过大时随时间(天一般),CLOSE_WAIT套接字建立在服务器上盒(netstat的 - ),长周期的程度,过程中不会接受这样的问题任何进一步的连接。在这一点上,我们有反弹的过程和关闭它再次运行。

我们已经尝试运行我们的ASP.NET应用程序的一些负载测试,以试图复制问题(因为推断从代码中的一些问题是不可能的)。我们认为,我们已经成功这一点,并结束了一个Wireshark的包跟踪问题的表现自己作为一个SocketException套接字服务器的日志:

  

System.Net.Sockets.SocketException:一个现有的连接被强行关闭远程主机   在System.Net.Sockets.Socket.BeginSend(字节[]缓冲液,的Int32偏移的Int32大小,的SocketFlags的SocketFlags,AsyncCallback的回调,对象状态)

我试图从包跟踪重现该问题作为一个单线程程序直接对话套接字服务器(使用相同的代码的ASP.NET应用程序那样),我无法。

有没有人得到了接下来的事情就任何建议去尝试,检查或者我们可以做明显的事情错了?

有帮助吗?

解决方案

看的图

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

您的客户端关闭通过调用close()的连接,它发送FIN到服务器的插座,其获得确认的FIN且其现在改为CLOSE_WAIT状态,并保持这种方式,除非服务器问题的close()上调用插座。

您服务器程序需要检测所述客户端是否已经终止的连接,然后关闭()它立即释放的端口。怎么样?请参考read()。一旦读取结束的文件(被接收的意思FIN),返回零。

其他提示

如果您的服务器正在积累CLOSE_WAIT插座,则它不会关闭其套接字连接完成时。如果你看看状态图中的克里斯后的评论,你会看到,一旦关闭套接字和CLOSE_WAIT已经发送了LAST_ACK过渡到FIN

您说,这是复杂的,以确定要做到这一点,由于异步性质是什么?这不应该是一个问题,如果从您的recv回调返回0字节,你应该关闭套接字(假设你有没有别的事情可做,一旦你的客户端关闭连接的侧面)。如果您还需要担心继续发送,然后做一个关机(RECV)这里并记录您的客户端已经关闭,一旦你完成发送做一个关机(发送)和关闭。

您可以在从它返回0,表明客户端已经关闭,这可能会导致您的问题读回调发出新的读?

  

在客户端负责关闭连接的。

客户端和服务器必须关闭和关闭套接字。无论是客户端未完成关闭(不太可能 - 因为这将会有它的终结器运行)或服务器没有关闭套接字(可能)

using (Socket s = new Socket(/* */)) {
  /* Do stuff */
  s.Shutdown(SocketShutdown.Both);
  s.Close();
}

您不应该离开关闭TCP套接字只到客户端的责任。会发生什么,如果客户端进程/机器死机?

理想情况下,应该有一个超时到位,这样,如果接收到上一个连接的套接字它获取由服务器关闭的一定量的时间在此之后没有流量。

无论何时在插座上的所有操作已经由客户端完成,它并不需要做的插座上的任何更多的读操作,客户端应该发出关闭命令会发生什么。

关闭命令发出此,简单地告诉监听器(服务器),该连接需要被关闭。

在简单的话,当服务器(在异步模式下listener.read()或listener.beginread(...))再次发出读命令,读出将返回一个0字节读,这本身表明插座需要被收听者闭合,在插座上的任何其它操作已经由客户端停止。

CLOSE_WAIT的意指一个套接字被关闭后流连了一会儿,以防止重新使用相同的套接字号和接收从旧连接的数据包。这只会让你悲伤,如果你打开和真的很快关闭插座的数量huuuuge

编辑 - 。它应该是TIME_WAIT,不CLOSE_WAIT上述

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top