Read() blocking problem
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.
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, 2022Comments
-
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:
- Client connect to server with a request
- Server handles request
- Server waits to see if client has any more requests
- 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 almost 15 yearsCould you use UDP instead and make it connectionless?
-
Reed Copsey almost 15 yearsHe already is spawning a new thread per client, in which case using BeginRead makes less sense....
-
rookie almost 15 yearsIt makes more sense than using sleep. msmvps.com/blogs/peterritchie/archive/2007/04/26/…
-
rookie almost 15 years
-
Reed Copsey almost 15 yearsI 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 almost 15 yearsSpencer: 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 almost 15 yearsIf 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 almost 15 yearsAnd it still makes less sense than my answer.
-
Reed Copsey almost 15 yearsYes - I was suggesting a loop with a blocking mechanism of some form.
-
rookie almost 15 yearsAnd what releases the block? Another thread polling the client stream for data? How is that a better idea than BeginRead()?
-
Reed Copsey almost 15 yearsWaitHandle.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 almost 15 yearsThat's no better if there's nothing to release the handle. See my answer.
-
Admin almost 15 yearsIt 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 almost 15 yearsSetup 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.