我正在编写一个只使用一个套接字的简单套接字客户端。所以我想我可以为所有接收操作重用一个SocketAsyncEventArgs。只要连接插座,它就能正常工作。当服务器断开连接时,客户端将在控制台中输入无限接收循环垃圾邮件“接收成功”。
套接字断开时,不应该是e.SocketError!= SocketError.Success为真吗?
以下是代码的一部分:
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);
}
答案 0 :(得分: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();
}
当然,你还需要阻止你的客户尝试使用套接字,但我相信你可以解决这个问题。