title: Why is NetworkStream.Read so slow?
body: <p>I know, there are already a lot of similar questions here but I did not found a solution to make it faster or the reason why it is so slow?</p>
  
  <p>We have an application in C#.NET that needs to communicate through TCP to a device that answers on the same TCP stream (all in bytes). The sending of messages goes pretty fast (about 20 ms) but when we Read the data from the TCP socket with the NetworkStream.Read() method (or similar Socket.Receive()) it takes about 600ms. I get this number by starting a stopwatch before the Read method and stop it right after the Read.</p>
  
  <p>I also log the traffic with Wireshark and there I see that the communication goes pretty fast (with the TCPNoDelay and TCPAckFrequency registry hacks) but there I saw that the following message that is send to the device is after 600ms (after the reading of the previous answer).</p>
  
  <p>The devices cannot handle multiple messages at once and they also answer with a custom made Acknowledge so that our program knows that the last sent message is received and constructed right.</p>
  
  <p>Ok here is some testing code that I have for a Console application and even that has the problem of the 600ms delay at reading.</p>
  
  <pre><code>try
  {
     if (!retry)
     {
        Console.WriteLine("Please enter the IP address you want to check:");
        ip = Console.ReadLine();
        Console.WriteLine("Please enter the port where you want to check on:");
        port = Convert.ToInt32(Console.ReadLine());
        Console.WriteLine("Connecting to {0}: {1}", ip, port);
        Console.WriteLine("Please enter the message you want to write to the specified port:");
        message = Console.ReadLine();
     }
     tcp = new TcpClient(ip, port);
     tcp.NoDelay = true;
     tcp.Client.NoDelay = true;
     Stopwatch sWrite = new Stopwatch();
     Stopwatch sRead = new Stopwatch();
     Stopwatch sDataAvailable = new Stopwatch();
     using (NetworkStream ns = tcp.GetStream())
     {
        Byte[] data = System.Text.Encoding.ASCII.GetBytes(message + "\r");
        sWrite.Start();
        ns.Write(data, 0, data.Length);
        sWrite.Stop();
        data = new byte[256];
        sRead.Start();
        Console.WriteLine("There is data on the socket: {0}", ns.DataAvailable);
        int readBytes = ns.Read(data, 0, data.Length);
        sRead.Stop();
        message = System.Text.Encoding.ASCII.GetString(data, 0, readBytes);
        Console.WriteLine(message);
     }
     Console.WriteLine("The reading speed is {0} and the writing speed is {1}", sRead.ElapsedMilliseconds, sWrite.ElapsedMilliseconds);
  }
  catch { }
  finally
  {
     tcp.Close();
  }
  </code></pre>
  
  <p>And this gives the following result: <code>The reading speed is 500 and the writing speed is 0</code></p>