2010-07-03 7 views
-1

ce que mon programme fait est, À la première connexion accepter, le serveur envoie des données le client reçoit puis envoie à nouveau (Datasize ne change pas) Le serveur le reçoit puis renvoie encore .... cette boucle continue.octet fourni pour BeginReceive

lorsque le serveur reçoit des données pour la deuxième fois l'int retourné par endreceive(); est 0

bien que j'ai trouvé la solution, mais je ne sais pas pourquoi cela résoudre effectivement le problème

i lire somehewhere qu'il ya quelque chose appelé tampon « sale »: s

donc ce que je l'ai été .

//added line 
data = new byte[DataSize]; 

//now index works fine :s 
int index = socket.endreceive(result); 

précédemment j'ai été réutilisez byte[] data pour envoyer et recevoir des sans modifier son contenu, transmission des données est tous les zéros

et cela a fonctionné :)

msdn ne marche pas me aider là-bas ou ai-je manqué somwthing? MSDN Link

Ce code résume

private void OnSendCallBack(IAsyncResult result) 
    { 
     int id_client = (int)result.AsyncState; 
     try 
     { 

      int index = clientInfo[id_client].client.EndSend(result); 

      clientInfo[id_client].offsetSend += index; 
      if (index == 0) 
      { 
       Console.WriteLine("Index == 0"); 
       return; 
      } 
      else if (clientInfo[id_client].offsetSend < DataSize) 
      { 
       clientInfo[id_client].dataToSend = DataSize - clientInfo[id_client].offsetSend; 
       clientInfo[id_client].client.BeginSend(data, clientInfo[id_client].offsetSend, clientInfo[id_client].dataToSend, SocketFlags.None, RecieveCallBack, id_client); 
      } 
      else 
      { 
       clientInfo[id_client].offsetSend = 0; 
       clientInfo[id_client].dataToSend = DataSize; 
       //************************************* 
       data = new byte[DataSize]; // THIS IS THE PROBLEM HERE 
       //************************************* 
       clientInfo[id_client].client.BeginReceive(data, 0, data.Length, SocketFlags.None, RecieveCallBack, id_client); 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Send: " + ex.Message); 
     } 
    } 

private void RecieveCallBack(IAsyncResult result) 
    { 
     int id_client = (int)result.AsyncState; 

     try 
     { 

      int index = clientInfo[id_client].client.EndReceive(result); 

      //byte[] buffer = new byte[DataSize]; 
      //int received = clientInfo[id_client].client.Receive(buffer); 

      clientInfo[id_client].offsetRec += index; 
      if (index == 0) 
      { 
       index = clientInfo[id_client].client.EndReceive(result); 
       Console.WriteLine("Index == 0"); 
       return; 
      } 
      else if (clientInfo[id_client].offsetRec < DataSize && clientInfo[id_client].offsetRec != 0) 
      { 
       clientInfo[id_client].dataToReceive = DataSize - clientInfo[id_client].offsetRec; 
       clientInfo[id_client].client.BeginReceive(data, clientInfo[id_client].offsetRec, clientInfo[id_client].dataToReceive, SocketFlags.None, RecieveCallBack, id_client); 
      } 
      else 
      { 
       clientInfo[id_client].offsetRec = 0; 
       clientInfo[id_client].dataToReceive = DataSize; 

       if (clientInfo[id_client].RunNumber < RounCount) 
       { 
        clientInfo[id_client].RoundTripStat.EndSample(); 
        clientInfo[id_client].RoundTripStat.BeginSample(); 
        clientInfo[id_client].client.BeginSend(data, 0, data.Length, SocketFlags.None, OnSendCallBack, id_client); 
       } 

       Close(id_client); 
      } 

     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Server: " + ex.Message); 
     } 
    } 

J'ai fourni le code de SendCallback et recevoir Callback, comme vous pouvez voir une commande asynch attend un à la fois

Répondre

1

EndReceive() retourne 0 s'il Il n'y avait plus de données à recevoir, et le socket a été fermé (ie ne sera plus de données à recevoir).

Des documents dont vous parlez:

Si l'hôte distant arrête la connexion du socket avec la méthode d'arrêt, et toutes les données disponibles ont été reçues, la méthode EndReceive complètera immédiatement et retourner zéro octets.

Vous ne devriez pas réutiliser généralement le même tampon pour l'envoi et la réception - vous finirez par envoyer toutes les données que vous avez reçu, et si vous avez envoyer et de recevoir chevauchement asynchrone des appels, il va finir dans une très état étrange, potentiellement. Il est seulement sûr de "partager" le tampon si vous effectuez seulement une opération à la fois, et vous vous assurez que lorsque vous écrivez, vous avez exactement les données que vous voulez, explicitement définies là.

+0

oui, j'effectue une opération à la fois, mais, avant de recevoir si je ne fais pas de données = nouvel octet [DataSize] ... je reçois 0 de EndReceive (...) et le drapeau de douille; 'Connected' est automatiquement mis à false: s –

+0

@KiNGPiN: Cela semble extrêmement étrange - êtes-vous sûr que ce n'est pas parce que vous avez envoyé des données incorrectes? Un programme court mais complet démontrant le problème aiderait vraiment ici. –

+0

j'ai mis à jour la question avec l'extrait de code, comme vous pouvez le voir dans SendCallBack je commence le BeginReceive ... envoyer est seulement rappelé encore une fois que les données ont reçu et le code est simple aucune manipulation de données que ce soit –