2009-09-02 74 views
4

我正在寫一個簡單的套接字客戶端,它只使用一個套接字。所以我想我可以重複使用一個SocketAsyncEventArgs進行所有接收操作。只要插座已連接,它就可以正常工作。當服務器斷開連接時,客戶端將在控制檯中輸入無限的接收循環垃圾郵件「接收成功」。重複使用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(); 
} 

當然,你還需要從嘗試使用socket停止你的客戶,但我敢肯定,你可以工作的那部分。

+0

謝謝。這是一個簡單的解決方案,它解決了這個問題:) – remdao 2009-09-02 09:08:31

+0

也許你可以'勾選'我的答案是正確的嗎? :) – 2009-09-03 00:57:26