Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8737919
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T10:37:47+00:00 2026-06-13T10:37:47+00:00

I’ve been struggling with this and can’t find a reason why my code is

  • 0

I’ve been struggling with this and can’t find a reason why my code is failing to properly read from a TCP server I’ve also written. I’m using the TcpClient class and its GetStream() method but something is not working as expected. Either the operation blocks indefinitely (the last read operation doesn’t timeout as expected), or the data is cropped (for some reason a Read operation returns 0 and exits the loop, perhaps the server is not responding fast enough). These are three attempts at implementing this function:

// this will break from the loop without getting the entire 4804 bytes from the server 
string SendCmd(string cmd, string ip, int port)
{
    var client = new TcpClient(ip, port);
    var data = Encoding.GetEncoding(1252).GetBytes(cmd);
    var stm = client.GetStream();
    stm.Write(data, 0, data.Length);
    byte[] resp = new byte[2048];
    var memStream = new MemoryStream();
    int bytes = stm.Read(resp, 0, resp.Length);
    while (bytes > 0)
    {
        memStream.Write(resp, 0, bytes);
        bytes = 0;
        if (stm.DataAvailable)
            bytes = stm.Read(resp, 0, resp.Length);
    }
    return Encoding.GetEncoding(1252).GetString(memStream.ToArray());
}

// this will block forever. It reads everything but freezes when data is exhausted
string SendCmd(string cmd, string ip, int port)
{
    var client = new TcpClient(ip, port);
    var data = Encoding.GetEncoding(1252).GetBytes(cmd);
    var stm = client.GetStream();
    stm.Write(data, 0, data.Length);
    byte[] resp = new byte[2048];
    var memStream = new MemoryStream();
    int bytes = stm.Read(resp, 0, resp.Length);
    while (bytes > 0)
    {
        memStream.Write(resp, 0, bytes);
        bytes = stm.Read(resp, 0, resp.Length);
    }
    return Encoding.GetEncoding(1252).GetString(memStream.ToArray());
}

// inserting a sleep inside the loop will make everything work perfectly
string SendCmd(string cmd, string ip, int port)
{
    var client = new TcpClient(ip, port);
    var data = Encoding.GetEncoding(1252).GetBytes(cmd);
    var stm = client.GetStream();
    stm.Write(data, 0, data.Length);
    byte[] resp = new byte[2048];
    var memStream = new MemoryStream();
    int bytes = stm.Read(resp, 0, resp.Length);
    while (bytes > 0)
    {
        memStream.Write(resp, 0, bytes);
        Thread.Sleep(20);
        bytes = 0;
        if (stm.DataAvailable)
            bytes = stm.Read(resp, 0, resp.Length);
    }
    return Encoding.GetEncoding(1252).GetString(memStream.ToArray());
}

The last one “works”, but it certainly looks ugly to put a hard-coded sleep inside the loop considering that sockets already support read timeouts! Do I need to setup some property(ies) on the TcpClient of the NetworkStream? Does the problem resides in the server? The server don’t close the connections, it is up to the client to do so. The above is also running inside the UI thread context (test program), maybe it has something to do with that…

Does someone know how to properly use NetworkStream.Read to read data until no more data is available? I guess what I’m wishing for is something like the old Win32 winsock timeout properties… ReadTimeout, etc. It tries to read until the timeout is reached, and then return 0… But it sometimes seem to return 0 when data should be available (or on the way.. can Read return 0 if is available?) and it then blocks indefinitely on the last read when data is not available…

Yes, I’m at a loss!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T10:37:49+00:00Added an answer on June 13, 2026 at 10:37 am

    I answered (and asked) this back in 2012. Now in 2023 I’m using a much improved method to handle "timeout-based" End of Message (EOM) protocols, which I’ll share in place of the original, outdated and wrong answer.

    I can’t stress enough how bad is any protocol in which termination is based on a read/connection timeout. The amount of pain I suffered trying to handle this is hard to express. But, as was my case, I could not change the other end, so I had to come up with ideas to mitigate the problems and make it as performant as possible, and I think that I now have the best possible bad solution to this 🙂

    The basic idea remains the same as in the original answer: read data until no more data arrives after a specified inter-read timeout. It now improves it by adding a special case for the initial read to wait for data to start arriving with a "larger" initial timeout.

    I’ve separated the reading code from the sending code. To read until "timeout" I’m now using the following:

    public static void WaitForData(this NetworkStream stream, TimeSpan? timeout) {
        if (timeout is null) return;
        int originalReadTimeout = stream.ReadTimeout;
        stream.ReadTimeout = (int)timeout.Value.TotalMilliseconds;
        // performs a zero-byte read, e.g., don't read but waits for data unless the readtimeout is reached
        _ = stream.Read(Array.Empty<byte>(), 0, 0);
        stream.ReadTimeout = originalReadTimeout;
    }
    
    public static ReadOnlySpan<byte> ReadUntilTimeout(this NetworkStream stream, 
        TimeSpan? startTimeout = null,
        TimeSpan? readTimeout = null,
        int bufferSize = 8192 // same as TcpClient ReceiveBufferSize
        ) {
        stream.ReadTimeout = (int?)readTimeout?.TotalMilliseconds ?? stream.ReadTimeout;
        // if no data arrives within the start timeout a SocketException will be thrown!
        // ReadTimeout is automatically reset inside the wait bellow after it completes
        stream.WaitForData(startTimeout);
        var writer = new ArrayPoolBufferWriter<byte>();
        int readSize = -1;
        try {
            while (readSize != 0) {
                var buffer = writer.GetSpan(bufferSize);
                readSize = stream.Read(buffer);
                writer.Advance(readSize);
            }
        } catch(IOException ioe) when (ioe.InnerException is SocketException soe) {
            // ignores read timeout errors since that's what we want: read until closed or no more data available
            if (soe.SocketErrorCode != SocketError.TimedOut)
                throw soe;
        }
        return writer.WrittenSpan;
    }
    

    It improves in many ways my original answer, and also on other answers found here, as it doesn’t use Thread.Sleep, Spin.Wait or DataAvailable to check for data, it directly employs zero-byte reads against the underlying Socket, which will wait for data to arrive only if needed and in a very performant way, without any allocations whatsoever, and then proceed with the reads, until a read timeout is detected when data doesn’t arrive in time.

    It’s easy to see how brittle this protocol is, since any network condition could affect the data transfer rate and trigger the timeout while there’s still data to be received. But, it’s the best way I found to handle this kind of predicament.

    The SendCmd method could be rewritten like this:

    static string SendCmd(string cmd, string ip, int port) {
        var client = new TcpClient(ip, port);
        var data = Encoding.GetEncoding(1252).GetBytes(cmd);
        var stm = client.GetStream();
        stm.Write(data, 0, data.Length);
        stm.Flush();
        var readSpan = stm.ReadUntilTimeout(
            startTimeout: TimeSpan.FromSeconds(10), 
            readTimeout: TimeSpan.FromMilliseconds(20));
        return Encoding.GetEncoding(1252).GetString(readSpan.ToArray());
    }
    

    You’ll notice that I’m using newer .NET constructions like ReadOnlySpan<byte> and also the amazing ArrayPoolBufferWriter from https://github.com/CommunityToolkit/dotnet which performs much better than MemoryStream for this kind of scenario.

    I’ll also publish a nuget package with all these (hopefully) high performance networking functions wrapped for instant use.


    OLD ANSWER (2012) for reference

    Setting the underlying socket ReceiveTimeout property did the trick. You can access it like this: yourTcpClient.Client.ReceiveTimeout. You can read the docs for more information.

    Now the code will only "sleep" as long as needed for some data to arrive in the socket, or it will raise an exception if no data arrives, at the beginning of a read operation, for more than 20ms. I can tweak this timeout if needed. Now I’m not paying the 20ms price in every iteration, I’m only paying it at the last read operation. Since I have the content-length of the message in the first bytes read from the server I can use it to tweak it even more and not try to read if all expected data has been already received.

    I find using ReceiveTimeout much easier than implementing asynchronous read… Here is the working code:

    string SendCmd(string cmd, string ip, int port)
    {
      var client = new TcpClient(ip, port);
      var data = Encoding.GetEncoding(1252).GetBytes(cmd);
      var stm = client.GetStream();
      stm.Write(data, 0, data.Length);
      byte[] resp = new byte[2048];
      var memStream = new MemoryStream();
      var bytes = 0;
      client.Client.ReceiveTimeout = 20;
      do
      {
          try
          {
              bytes = stm.Read(resp, 0, resp.Length);
              memStream.Write(resp, 0, bytes);
          }
          catch (IOException ex)
          {
              // if the ReceiveTimeout is reached an IOException will be raised...
              // with an InnerException of type SocketException and ErrorCode 10060
              var socketExept = ex.InnerException as SocketException;
              if (socketExept == null || socketExept.ErrorCode != 10060)
                  // if it's not the "expected" exception, let's not hide the error
                  throw ex;
              // if it is the receive timeout, then reading ended
              bytes = 0;
          }
      } while (bytes > 0);
      return Encoding.GetEncoding(1252).GetString(memStream.ToArray());
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

For some reason, after submitting a string like this Jack’s Spindle from a text
Does anyone know how can I replace this 2 symbol below from the string
I have a jquery bug and I've been looking for hours now, I can't
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I have this code to decode numeric html entities to the UTF8 equivalent character.
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
link Im having trouble converting the html entites into html characters, (&# 8217;) i
this is what i have right now Drawing an RSS feed into the php,
This could be a duplicate question, but I have no idea what search terms

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.