Read() blocking problem

11,493

NetworkStream.Read and ReadByte should block until the timeout if there's no data to read. I think it's far more likely that the call is reading something, probably a bunch of zeroes. Check the data being sent by the client carefully.

Share:
11,493
Justin Johnson
Author by

Justin Johnson

I'm a web application generalist. I paid my dues in the website world writing complex JavaScript applications powered by PHP REST APIs, and writing almost every kind of CMS tool you can think of. Currently, I'm working on an MMO in an end-to-end capacity. I almost entirely own the server components and REST APIs written in Java, I entirely own all of the Python/PHP CMS and support tools, and I implement UI features in C#/Unity for the game client. SOreadytohelp

Updated on June 04, 2022

Comments

  • Justin Johnson
    Justin Johnson almost 2 years

    I'm developing a server application in C#. Clients can connect to the server and make various requests. Currently, when a client connects I spawn a new thread to handle the request(s). I'm using the TCPClient class to handle client connections. My server works as follows:

    1. Client connect to server with a request
    2. Server handles request
    3. Server waits to see if client has any more requests
    4. If client does not make another request within some timeout period, the server kills the connection

    My problem is the following:

    When I read from the NetworkStream object that I get from the TCPClient class, the NetworkStream Read() method does not block if there is no Data Available. When the server reaches step #3, I would like to set some timeout on the NetworkStream and if the client does not make any more requests within that duration the server should kill the connection when that timeout exception is thrown. When my server reaches step 3, the NetworkStream Read() method does not block, reguardless of what I set it's ReadTimeout property to be. Can anyone help me out, or suggest a better way to do what I'm trying to do.

    Thanks

    • Admin
      Admin almost 15 years
      Could you use UDP instead and make it connectionless?
  • Reed Copsey
    Reed Copsey almost 15 years
    He already is spawning a new thread per client, in which case using BeginRead makes less sense....
  • rookie
    rookie almost 15 years
    It makes more sense than using sleep. msmvps.com/blogs/peterritchie/archive/2007/04/26/…
  • rookie
    rookie almost 15 years
  • Reed Copsey
    Reed Copsey almost 15 years
    I don't always agree with Peter Richie's arguments in there, particularly in user constructed threads. He even (in the discussion) advocates using Thread.Sleep(1) in some cases. That being said, in this case, I think using a WaitHandle is probably a better design, so I changed my answer.
  • Reed Copsey
    Reed Copsey almost 15 years
    Spencer: I edited my answer to adjust using a waithandle, but in this case, I don't necessarily believe sleep is a bad thing - it really depends on whether or not the amount of time slept is critical (since Richie's main argument is that SleepEx provides no timeout or guarantee that you'll return in the time you request).
  • rookie
    rookie almost 15 years
    If the client thread is waiting for data but only using the Read() method it will need to be looping until data is available. If you don't use Sleep() with Read() that's even worse.
  • rookie
    rookie almost 15 years
    And it still makes less sense than my answer.
  • Reed Copsey
    Reed Copsey almost 15 years
    Yes - I was suggesting a loop with a blocking mechanism of some form.
  • rookie
    rookie almost 15 years
    And what releases the block? Another thread polling the client stream for data? How is that a better idea than BeginRead()?
  • Reed Copsey
    Reed Copsey almost 15 years
    WaitHandle.WaitOne allows a timeout to be specified. THis was actually Peter Richie's suggestion to many people to avoid sleep in operations like this...
  • rookie
    rookie almost 15 years
    That's no better if there's nothing to release the handle. See my answer.
  • Admin
    Admin almost 15 years
    It seems that I can't set a timeout duration on a BufferedStream wrapped around a NetworkStream (System.InvalidOperationException: Timeouts are not supported on this stream...) So, I would still have to handle the timeout manually if I went this route
  • Charlie
    Charlie almost 15 years
    Setup timers to handle the timeouts. when the timer closes the socket an exception will be thrown on the read method. Then when data is read, reset the timer.