1

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>"
John Saunders
  • 160,644
  • 26
  • 247
  • 397
RB1987
  • 55
  • 1
  • 7

1 Answers1

1

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.
Community
  • 1
  • 1
JFish222
  • 1,026
  • 7
  • 11
  • :D No no its definitely removing the header only. But the problem here is with raw page which is before the header is stripped out. The page is not populated completely – RB1987 May 26 '15 at 03:47
  • Yup, brain fart it is! :) Is the Do loop iterating as expected? – JFish222 May 26 '15 at 04:05
  • Thanks @JFish222 I was in the process of trying WebClient. Gave it a shot and it works like a charm. Your comments about the TCPClient make sense. Although any idea why the async process would work on some ports, while not on others? – RB1987 May 26 '15 at 16:49
  • Happy to help! I'm not sure that what you were experiencing was port related so much as race condition related. Sometimes the data hits the destination on time, sometimes it doesn't. That's not to say that for some crazy reason traffic over the alternative port wasn't ever so slightly faster. (For example maybe your AV only applies scanning on specific ports for web and email traffic. Just making stuff up, you get the idea.) – JFish222 May 27 '15 at 06:34