RB1987
RB1987

Reputation: 55

Network stream doesn't receive all data

I am using network stream to send a command to a server and receive data back. For some reason I don't receive all the data back. I tried to keep the connection open in an infinite loop and see that on the next iteration the data is received. Also weirdly when I DON'T USE PORT 80 network stream behaves fine and receives the data properly.

Here is my receive function.

    public static string SendRecieveString(string hostname, int port, string message, bool stripHeaderFromRespose = true)
    {
        //Printer.print("TCP Socket: Attempting Connection to server: " + hostname + "@" + port + " with header: " + message, PrintingSeverities.Info);
        //using (WebClient client = new WebClient())
        //{
        //    Printer.print("Send/Recieve communicating with header: " + "http://" + hostname + message + ":" + port, PrintingSeverities.Debug);
        //    string htmlCode = client.DownloadString("http://" + hostname + message + ":" + port);
        //    Printer.print("Raw Page: \n " + htmlCode, PrintingSeverities.Debug);
        //    return htmlCode;
        //}
        #region v1
        try
        {
            string page = String.Empty;
            using (TcpClient clientHandler = new TcpClient(hostname, port))
            {
                if (clientHandler.Connected) { 
                using (NetworkStream clientStream = clientHandler.GetStream())
                {
                    if (!clientStream.CanRead || !clientStream.CanWrite)
                    {
                        Printer.print("TCP Socket: Stream cannont preform read/write", PrintingSeverities.Warning);
                        throw new Exception("TCP Socket: Stream cannont preform read/write");
                    }
                    Byte[] bytes2send = Encoding.ASCII.GetBytes(message);
                    clientStream.Write(bytes2send, 0, bytes2send.Length);
                    do
                    {
                        Byte[] bytesReceived = new Byte[clientHandler.ReceiveBufferSize];
                        int streamReceived = clientStream.Read(bytesReceived, 0, bytesReceived.Length);
                        page += Encoding.ASCII.GetString(bytesReceived, 0, streamReceived);
                        Printer.print("Stream size: " + streamReceived);
                    } while (clientStream.DataAvailable);
                    Printer.print("Raw Page: " + page, PrintingSeverities.Debug);
                }
                if (stripHeaderFromRespose)
                {
                    string HTTPHeaderDelimiter = "\r\n\r\n";
                    if (page.IndexOf("HTTP/1.1 200 OK") > -1)
                        page = page.Substring(page.IndexOf(HTTPHeaderDelimiter) + HTTPHeaderDelimiter.Length);
                }
                }
                else
                {
                    Printer.print("TCP Socket: Could not connect to server", PrintingSeverities.Warning);
                    throw new Exception("TCP Socket: Could not connect to server");
                }
            }
            Printer.print("TCP Socket: Returning Page: " + page, PrintingSeverities.Debug);

            return page;
        }
        catch (Exception ex)
        {
            throw ex;
        }
        #endregion

I am receiving this: Raw Page: HTTP/1.1 200 OK Cache-control: no-store Content-type: text/xml Content-length: 399

[End] --> While I should receive: Raw Page:

  HTTP/1.1 200 OK 
  Cache-control: no-store 
  Content-type: text/xml 
  Content-length: 399


<?xml version="1.0" encoding="utf-8" ?> <datavalues><relay1state>0</relay1state><relay2state>1</relay2state><reboot1state>0</reboot1state><reboot2state>0</reboot2state><failures1>0</failures1><failures2>0</failures2><rbtAttempts1>0</rbtAttempts1><rbtAttempts2>0</rbtAttempts2><totalreboots1>0</totalreboots1><totalreboots2>0</totalreboots2><serialNumber>00:0C:C8:02:B9:92</serialNumber></datavalues>"

Upvotes: 1

Views: 918

Answers (1)

JFish222
JFish222

Reputation: 1026

Update #10! :)

It looks like another thread agrees with my assessment below. See this StackOverFlow post for additional info.


The issue appears to be that you're checking if data is available from an async source. (In other words, the answer could be "not yet".)

Solutions:

  1. Use the WebClient library to do the work for you:

    var webClient = new WebClient();
    string readHtml = webClient.DownloadString(hostname);

  2. Staying with the method you original presented, try reading via

    • async mechanism via the TCPClient class.
    • StreamReader ReadToEnd (lacks buffering so you're forced to pull the entire dataset into a pre-defined byte array.
    • or utilize the total expected dataset size to determine if you're done, and have the thread sleep between buffer reads.

Upvotes: 1

Related Questions