web-dev-qa-db-fra.com

Comment obtenir toutes les données de NetworkStream

J'essaie de lire toutes les données présentes dans la mémoire tampon de la machine connectée via TCP/IP, mais je ne sais pas pourquoi je ne reçois pas toutes les données, certaines données sont en train de manquer… .. Voici le code que j'utilise ..

using (NetworkStream stream = client.GetStream())
{
    byte[] data = new byte[1024];
    int numBytesRead = stream.Read(data, 0, data.Length);
    if (numBytesRead > 0)
    {
       string str= Encoding.ASCII.GetString(data, 0, numBytesRead);
    }
}

S'il vous plaît dites-moi ce qui me manque pour obtenir toutes les données de la machine ..__ Merci d'avance ..

10
shubham Hegdey

Le problème avec votre code est que vous n'obtiendrez pas toutes les données si leur taille est supérieure à la taille de la mémoire tampon (1024 octets dans votre cas), vous devez donc lire le flux dans la boucle. Ensuite, vous pouvez Write toutes les données contenues dans une MemoryStream jusqu'à la fin de la NetworkStream.


      string str;
      using (NetworkStream stream = client.GetStream())
      {
            byte[] data = new byte[1024];
            using (MemoryStream ms = new MemoryStream())
            {

                int numBytesRead ;
                while ((numBytesRead = stream.Read(data, 0, data.Length)) > 0)
                {
                    ms.Write(data, 0, numBytesRead);


                }
               str = Encoding.ASCII.GetString(ms.ToArray(), 0, (int)ms.Length);
            }
        }
19
GeorgeChond

Cet exemple de MSDN: NetworkStream.DataAvailable montre comment vous pouvez utiliser cette propriété pour le faire:

// Examples for CanRead, Read, and DataAvailable. 
// Check to see if this NetworkStream is readable. 
if(myNetworkStream.CanRead)
{
    byte[] myReadBuffer = new byte[1024];
    StringBuilder myCompleteMessage = new StringBuilder();
    int numberOfBytesRead = 0;

    // Incoming message may be larger than the buffer size. 
    do{
         numberOfBytesRead = myNetworkStream.Read(myReadBuffer, 0, myReadBuffer.Length);

         myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));

    }
    while(myNetworkStream.DataAvailable);

    // Print out the received message to the console.
    Console.WriteLine("You received the following message : " +
                                 myCompleteMessage);
}
else
{
     Console.WriteLine("Sorry.  You cannot read from this NetworkStream.");
}
5
dariogriffo

Essayez ce code: 

using (NetworkStream stream = client.GetStream())
    {
         do
         {
           Thread.Sleep(20);
         } while (!stream.DataAvailable);

         if (stream.DataAvailable && stream.CanRead)
         {
              Byte[] data = new Byte[1024];
              List<byte> allData = new List<byte>();

              do
              {
                    int numBytesRead = stream.Read(data,0,data.Length);

                    if (numBytesRead == data.Length)
                    {
                         allData.AddRange(data);
                    }
                    else if (numBytesRead > 0)
                    {
                         allData.AddRange(data.Take(bytes));
                    }                                    
               } while (stream.DataAvailable);
          }
    }

J'espère que cela vous aidera, cela devrait vous éviter de manquer les données qui vous sont envoyées. 

2
Paul Weiland

Essaye ça:

 private string GetResponse(NetworkStream stream)
    {
        byte[] data = new byte[1024];
        using (MemoryStream memoryStream = new MemoryStream())
        {
            do
            {
                stream.Read(data, 0, data.Length);
                memoryStream.Write(data, 0, data.Length);
            } while (stream.DataAvailable);

            return Encoding.ASCII.GetString(memoryStream.ToArray(), 0, (int)memoryStream.Length);
        }
    }
1
Popa Andrei

pour mon scénario, le message lui-même indiquait la longueur du message suivant. voici le code

 int lengthOfMessage=1024;
 string message = "";
 using (MemoryStream ms = new MemoryStream())
 {
      int numBytesRead;
      while ((numBytesRead = memStream.Read(MessageBytes, 0, lengthOfMessage)) > 0)
      {
            lengthOfMessage = lengthOfMessage - numBytesRead;
            ms.Write(MessageBytes, 0, numBytesRead);
      }
      message = Encoding.ASCII.GetString(ms.ToArray(), 0, (int)ms.Length);
 }
0
Asad Durrani

TCP lui-même ne dispose d'aucun moyen de définir la condition de "fin des données". Cette responsabilité incombe au niveau de l'application portocol. 

Par exemple, voir HTTP description de la requête: 

Une demande client (composée dans ce cas de la ligne de demande et d'un seul champ d'en-tête) est suivie d'une ligne vide, de sorte que la demande se termine par une double nouvelle ligne.

Ainsi, pour la demande, la fin des données est déterminée par deux séquences de nouvelle ligne. Et pour la réponse:

Content-Type spécifie le type de média Internet des données acheminées par le message HTTP, tandis que Content-Length indique sa longueur en octets.

La taille du contenu de la réponse est spécifiée dans l'en-tête avant les données. C’est donc à vous de décider comment encoder la quantité de données transférée en une seule fois - il ne peut s'agir que des premiers 2 ou 4 octets au début de la taille totale de la banque de données à lire ou de manière plus complexe si nécessaire.

0
dewaffled

J’ai rejoint cette question un peu tard, mais je me demandais quelle était la meilleure façon de le faire. Quand le protocole n'est pas connu ... Et voici ma conclusion

Les boucles while mentionnées dans les réponses précédentes ne fonctionnent pas correctement sur NetworkStream, elles échouent et vous n'obtenez aucune donnée.

Je n'ai pas essayé DataAvailable et, ne sachant pas comment cela fonctionne, je préfère une version que tout le monde peut comprendre.

var ms = new MemoryStream();
byte[] data = new byte[1024];
int numBytesRead;

do
{
    numBytesRead = stream.Read(data, 0, data.Length);
    ms.Write(data, 0, numBytesRead);

} while (numBytesRead == data.Length);

var str = Encoding.ASCII.GetString(ms.ToArray());
0
Johan Sonesson