2009-12-21 4 views
2

Comme dans le code simplifié ci-dessous, est-ce que vérifier que SendAsync() a fini de transmettre tous les octets prévus dans la mémoire tampon? Ou est-ce redondant? C'est pour une connexion TCP. Je suis particulièrement concerné par l'émission d'un second sous-appel à SendAsync() dans ProcessSend(). Par exemple, si plusieurs threads transmettaient des données à un client en utilisant un nouveau SocketAsyncEventArg (groupé) pour chaque message, n'est-il pas possible qu'un envoi simultané puisse s'interposer entre un message partiellement transmis? Ou est-ce une bonne raison pour un accès contrôlé au client en n'autorisant qu'un seul SocketAsyncEventArg à être utilisé dans l'envoi de données?Vérifier si SendAsync a fini d'envoyer

private void ProcessSend(SocketAsyncEventArgs e) 
{ 
    // Check that data was sent 
    if ((e.SocketError == SocketError.Success) && (e.BytesTransferred > 0)) 
    { 
     AsyncSendUserToken token = (AsyncSendUserToken)e.UserToken; 

     // Check that all the data was sent 
     int offset = e.Offset + e.BytesTransferred; 
     if (offset < e.Count) 
     { 
      // Call send again to finish the send 
      e.SetBuffer(offset, e.Count - offset); 
      bool _willRaiseEvent = token.Socket.SendAsync(e); 
      if (!_willRaiseEvent) 
       ProcessSend(e); 
     } 
    } 
} 
+0

J'ai aussi vu cela se produire et j'ai aussi vu cas où le nombre d'octets transférés était supérieur à e.Count - e.Offset. Je réutilisais l'un SocketAsyncEventArgs pour l'envoi, et appel une méthode qui remplit le tampon et appelle SendAsync de ProcessSend. J'ai ajouté du code pour disposer l'actuel SocketAsynEventArgs dans ProcessSend et en créer un nouveau et cela a arrêté cette erreur. –

Répondre

2

Je suppose que vous lisez l'exemple à http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx et voir qu'ils vérifient la longueur des octets sur ProcessReceive. Ceci est fait dans le but d'obtenir tous les octets reçus, car vous n'avez aucun contrôle sur le nombre d'octets envoyés par l'autre partie à chaque fois.

Lorsque vous effectuez un envoi, ceci est redondant car le framework gère l'envoi de toutes vos données pour vous.

1

Je pense qu'il ya quelque chose de mal dans votre code:

// Check that all the data was sent 
int offset = e.Offset + e.BytesTransferred; 
if (offset < e.Count) 
{ 

e.Count est le nombre d'octets à transférer, ce n'est pas un décalage dans le tableau d'octets.

Ainsi, afin de comparer des pommes avec des pommes, vous diriez:

si (e.BytesTransfered < e.Count) {}