0

我正在尝试使用 Sockets,并构建了一个相当简单的 TCP 服务器。

此处提供代码:http: //pastebin.com/zLRaBc0q

我在从客户端停止 Socket 服务器时遇到问题。在 pastebin 中,start on line 136to192是服务器终止的处理程序。

背后的逻辑相当简单:

  • 断开请求的客户端;
  • 从连接的客户端列表中删除客户端;
  • 断开并删除其余的客户端;
  • 关闭服务器;
  • 从列表中删除服务器。

该程序完美地执行了上述内容,但它以某种方式设法在它的末尾挤进了一个额外的步骤 - 似乎意外执行ReceiveCallback(好吧,这对我来说是意外的),然后以ObjectDisposedExceptionfor line结束100

private static void ReceiveCallback(object sender, SocketAsyncEventArgs e)
{
    Socket client = (Socket)sender;
    Socket listener = (Socket)e.UserToken;

    string message = Encoding.ASCII.GetString(e.Buffer, e.Offset, e.BytesTransferred);

    // L100
    //  \/
    IPEndPoint clientCoordinates = client.RemoteEndPoint as IPEndPoint;
    IPEndPoint serverCoordinates = listener.LocalEndPoint as IPEndPoint;  

    Console.WriteLine("{0} bytes from {1} on {2}", e.BytesTransferred, clientCoordinates, serverCoordinates);

显然,它在关闭过程中无法访问client。这里的问题是,我不明白为什么程序甚至ReceiveCallback再次进入。我在处理退出消息后返回 void而不启动另一个调用它。

值得一提的是,只有当有两个客户端连接时才会发生这种情况。对于一个客户,它会毫无问题地停止。

尽管如此,(对我而言)描绘的是,它不是以requesting client结尾ObjectDisposedException,而是以另一个结尾。这仍然对我没有帮助,因为无论如何,我不明白为什么ReceiveCallback再次调用 - 客户端已断开连接,应该在我停止服务器之前将其标记为这样。

如何使服务器停止而没有ObjectDisposedException

PS对我来说,括号只是旁注。由于我是异步 + 线程的新手,我不明白某些行为是如何发生的。

4

1 回答 1

0

可以通过在回调顶部添加额外的检查来解决此问题:

// Handle errors.
if (e.SocketError != SocketError.Success)
{
    Console.WriteLine("Socket error: {0}", e.SocketError.ToString());
    return;
}

SocketAsyncEventArgs.Completed在所有情况下运行,但SocketError将设置为不同的值。

在我的情况下,它被设置为SocketError.OperationAborted(什么是真的),我只需要进行特殊处理 - 在我的情况下,用简单的return;.

于 2014-06-11T06:30:44.957 回答