2009-09-02 8 views
4

Je suis en train d'écrire un simple socket client qui n'utilise qu'une seule socket. Donc j'ai pensé que je pourrais réutiliser un seul SocketAsyncEventArgs pour toutes les opérations de réception. Cela fonctionne bien tant que le socket est connecté. Lorsque le serveur se déconnecte, le client entrera dans une boucle de réception infinie spamming "Réussite" dans la console.Réutilisation de SocketAsyncEventArgs avec ReceiveAsync en boucle infinie

Ne devrait pas e.SocketError! = SocketError.Success être vrai lorsque le socket est déconnecté?

Voici une partie du code:

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

Répondre

6

Si votre prise est configuré pour un flux d'octets, alors vous pouvez obtenir un rappel avec zéro octets, cela indique qu'une fermeture gracieuse de la prise a eu lieu et que plus d'octets ne seront jamais lus. Il suffit de vérifier cela dans votre code, par ex.

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

Bien sûr, vous aurez également besoin d'arrêter votre client d'essayer d'utiliser la prise, mais je suis sûr que vous pouvez travailler sur cette partie.

+0

Merci. C'était une simple salve et cela a résolu le problème :) – remdao

+0

Peut-être que vous pourriez «cocher» ma réponse comme correcte alors? :) –

Questions connexes