shubham Hegdey
shubham Hegdey

Reputation: 507

How to get all data from NetworkStream

I am trying to read all data present in the buffer of the Machine connected through TCP/IP but i don't know why i am not getting all data ,some data is getting Missed. Here is the code that i am using ..

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

Please tell me what i am missing to get all the data from the machine. Thanks in advance..

Upvotes: 17

Views: 54484

Answers (8)

shmnff
shmnff

Reputation: 739

The synchronous method sometimes does not display the request body. Using the asynchronous method always does.

string request = default(string);
StringBuilder sb = new StringBuilder();

byte[] buffer = new  byte[client.ReceiveBufferSize];
int bytesCount;

if (client.GetStream().CanRead)
{
    do
    {
        bytesCount = client.GetStream().ReadAsync(buffer, 0, buffer.Length).Result;
        sb.Append(Encoding.UTF8.GetString(buffer, 0, bytesCount));
    }
    while(client.GetStream().DataAvailable);

    request = sb.ToString();
}

Upvotes: 3

Stav Bodik
Stav Bodik

Reputation: 2134

@George Chondrompilas answer is correct but instead of writing it by yourself you can use CopyTo function which does the same :

https://stackoverflow.com/a/65188160/4120180

Upvotes: 0

Paul Weiland
Paul Weiland

Reputation: 737

Try this code:

using (NetworkStream stream = client.GetStream())
    {
         while (!stream.DataAvailable)
         {
             Thread.Sleep(20);
         }
        
         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(numBytesRead));
                    }                                    
               } while (stream.DataAvailable);
          }
    }
      

Hope this helps, it should prevent that you miss any data sended to you.

Upvotes: 3

Popa Andrei
Popa Andrei

Reputation: 2469

Try this:

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

Upvotes: 2

Asad Durrani
Asad Durrani

Reputation: 2237

for my scenario, the message itself was telling the length of subsequent message. here is the 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);
 }

Upvotes: 0

George Chondrompilas
George Chondrompilas

Reputation: 3247

The problem with your code is that you will not get all the data if the data size is bigger than the buffer size (1024 bytes in your case) so you have to Read the stream inside the loop. Then you can Write all the data inside a MemoryStream until the end of the 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);
            }
        }

Upvotes: 28

Dario Griffo
Dario Griffo

Reputation: 4274

This example from MSDN: NetworkStream.DataAvailable shows how you can use that property to do so:

// 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.");
}

Upvotes: 11

dewaffled
dewaffled

Reputation: 2983

TCP itself does not have any ways to define "end of data" condition. This is responsibility of application level portocol.

For instance see HTTP request description:

A client request (consisting in this case of the request line and only one header field) is followed by a blank line, so that the request ends with a double newline

So, for request end of data is determined by two newline sequences. And for response:

Content-Type specifies the Internet media type of the data conveyed by the HTTP message, while Content-Length indicates its length in bytes.

The response content size is specified in header before data. So, it's up to you how to encode amount of data transferred at once - it can be just first 2 or 4 bytes in the beginning of the data holding total size to read or more complex ways if needed.

Upvotes: 0

Related Questions