重用带有ReceiveAsync的SocketAsyncEventArgs导致无限循环

4
我正在编写一个简单的套接字客户端,它只使用一个套接字。因此,我想我可以重复使用一个SocketAsyncEventArgs来处理所有接收操作。只要套接字连接正常,这个方法就能正常工作。但是当服务器断开连接时,客户端将进入无限接收循环,在控制台上不断输出“Receive Success”。
当套接字断开连接时,e.SocketError != SocketError.Success应该为true,对吗?
以下是部分代码:
private void Completed(object sender, SocketAsyncEventArgs e)
{
   if (e.SocketError != SocketError.Success)
      status = 0;

   System.Console.WriteLine(e.LastOperation + " " + e.SocketError);

   if (status == 1)
   {
      switch (e.LastOperation)
      {
         case SocketAsyncOperation.Connect:
            ProcessConnect(e);
            break;
         case SocketAsyncOperation.Receive:
            ProcessReceive(e);
            break;
         case SocketAsyncOperation.Send:
            ProcessSend(e);
            break;
         default:
            status = 0;
            break;
      }
   }

   if (status != 1)
      CloseSocket();
}

private void ProcessReceive(SocketAsyncEventArgs e)
{
   if (!socket.ReceiveAsync(e))
      Completed(null, e);
}
1个回答

6
如果您的套接字设置为字节流,则可能会收到回调并返回零字节。这表示套接字已经优雅地关闭,并且不会再读取更多字节。在您的代码中,只需检查是否存在此情况即可,例如:
private void ProcessReceive( SocketAsyncEventArgs e )
{
    AsyncUserToken token = e.UserToken as AsyncUserToken;
    if( e.ByteTransferred > 0 && e.SocketError == SocketError.Success )
    {
        // .. process normally ..
    }
    else
    {
        CloseClientSocket( e );
    }
}

private void CloseClientSocket( SocketAsyncEventArgs e )
{
    AsyncUserToken token = e.UserToken as AsyncUserToken;
    try
    {
        token.Socket.Shutdown( SocketShutdown.Send );
    }
    // throws error if it's already closed
    catch( Exception ) {}
    token.Socket.Close();
}

当然,您还需要阻止客户端尝试使用套接字,但我相信您可以解决这部分问题。

谢谢。那是一个简单的解决方案,它解决了问题 :) - remdao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接