2009-09-02 31 views
4

ソケットを1つしか使用しない単純なソケットクライアントを作成しています。だから私はすべての受信操作のために単一のSocketAsyncEventArgsを再利用できると考えました。ソケットが接続されている限り正常に動作しています。サーバーが切断すると、クライアントはコンソールに「Receive Success」というスパムを送信する無限受信ループに入ります。SocketAsyncEventArgsをReceiveAsyncと再利用して無限ループの結果を返します

ソケットが切断されたときに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); 
} 

答えて

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(); 
} 

もちろん、あなたのクライアントがソケットを使用するのをやめさせる必要がありますが、私はあなたがその部分を使用できると確信しています。

+0

ありがとうございます。それは単純な洞察であり、それは問題を解決しました:) – remdao

+0

おそらく、あなたは私の答えを正確に '刻む'ことができましたか? :) –

関連する問題