CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13
  1. #1
    Join Date
    Jan 2007
    Posts
    102

    Socket Blocking Read TimeOut!

    After calling Socket.Read(...), the socket times out after 5000 ms. Because I set Socket.ReceiveTimout to 5000. If it times out, an exception occurs and catch the exception. But I don't need to do something, so it should loop again and the whole process repeats. The problem however, is at the first time Socket.Read(...) blocks for 5000 ms, which is great, but after Timeout exception, it loops and call Socket.Read(...) again, but this time it immediatly throws a SocketError "WouldBlock" and does this infinitely and my processor turns to 100%. Why this exception? It has to read in blockmode again until Timeout occurs!

    I googled and read some articles where they say WouldBlock means there is zero bytes received. I don't know about that, but than it should read in blocking mode again if nothing is received. My way of thinking is this. I establish a connection, than there is only a connection. The socket should than block if trying to read data, until I receive a few bytes, it's just that easy.
    Can someone help me out here, cause I don't really know what's going on in behind the mask of Socket class.

    Code:
    sock.ReceiveTimeout = 5000;
    socketState = true;
    while(socketState)
    {
    	try
    	{
    		int rcv = sock.Receive(buffer, buffer.Length, SocketFlags.None);
    		if (rcv > 0)
    		{
    			byte[] data = new byte[rcv];
    			Buffer.BlockCopy(buffer, 0, data, 0, rcv);
    			socketState = false;
    		}
    	}
    	catch (SocketException ex)
    	{
    		if ((ex.SocketErrorCode != SocketError.TimedOut) &&
    			(ex.SocketErrorCode != SocketError.WouldBlock) &&
    			(ex.SocketErrorCode != SocketError.IOPending) &&
    			(ex.SocketErrorCode != SocketError.NoBufferSpaceAvailable))
    		{
    			// Something is wrong with the socketconnection, so delete and try all over again
    			socketState = false;
    			e.Result = (object)null;
    		}
    		else
    		{
    			// Do nothing, just loop again!
    			// That's the BIG problem, when I call sock.Receive(...) again, it won't block for 5000 ms,
    			// but throws WouldBlock exception immediatly! Why??? I just want it to read in blocking mode again
    			// and throws an exception if it times out again!
    		}
    	}
    }

  2. #2
    Join Date
    Jul 2006
    Posts
    97

    Re: Socket Blocking Read TimeOut!

    Why don't you just set the timeout to 0 or -1 to wait infinitely?
    Using .NET 2.0

  3. #3
    Join Date
    Mar 2004
    Location
    33°11'18.10"N 96°45'20.28"W
    Posts
    1,808

    Re: Socket Blocking Read TimeOut!

    Quote Originally Posted by EmbeddedC View Post
    Can someone help me out here, cause I don't really know what's going on in behind the mask of Socket class.
    I can help there... there's nothing going on behind the scenes of the socket class. Its a direct object oriented wrapper around winsock. It adds no functionality over what is provided in ws2_32's recv function.

    I think you have a logic error in your implementation. packets are not guaranteed to be received all at once. I have no idea why you're setting a timeout to start with. standard recv blocks until a packet is received. from there all you need to do is validate that you've received all of the packet, and if not, continue to loop until the value returned from Receive is less than your buffer size (at which point you've typically received all of your packet, and can proceed to process the bytes).

    when the client disconnects it will throw an exception, but other than that you should be fine getting your packet bytes without a timeout.

  4. #4
    Join Date
    Jan 2007
    Posts
    102

    Re: Socket Blocking Read TimeOut!

    Dear friends,

    I use TimeOut because I run this piece of code in a seperate thread. To signal the thread that it has to close, I want to check, in the thread ofcourse, the signalstate periodically. So by using a timeout, I can get out off the blocking read and check the state and than try to read again.

    If I don't do that, it will block the thread infinitly and thus I can't terminate the thread, fromwhich an exception occur because the thread can't be closed.

    I hope you understand my situation.

  5. #5
    Join Date
    Mar 2004
    Location
    33°11'18.10"N 96°45'20.28"W
    Posts
    1,808

    Re: Socket Blocking Read TimeOut!

    receive only blocks if there is an active connection. when the socket disconnects, receive is unblocked w/ a socket exception.

    the only reason I can see for checking state would be to check for a client disconnect. since you don't have to do that, then I don't see why you'd have to poll like that.

  6. #6
    Join Date
    Jan 2007
    Posts
    102

    Re: Socket Blocking Read TimeOut!

    Thanks for the reply,

    What I did is wrote a simple server (in C++) which creates a new thread when accepted a clientconnection (which is the one written in C#). In the created thread of the server, I just kinda wait for an event for receiving data (by purpose). So it sends nothing, just waiting for some data to receive from the client.

    So there is only a simple connection and that's it! But another thing in C# is, that Socket.Connected seems to be false at that moment! Because there was no IO activity, that's kinda weird. It is connected (a bit confusing name), they could name it Socket.Idle = true or something.

    But I guess TimeOut is not the right thing to use, while to me the concept, to avoid hang up of a thread, is really the right thing to solve.

    So I'll try the disconnect() and see if Socket.Read(...) will come out of blocking mode.

  7. #7
    Join Date
    Jan 2007
    Posts
    102

    Re: Socket Blocking Read TimeOut!

    MadHatter,

    I disconnected the socket while it was connected, but Socket.Read(...) didn't return with an exception or something it just kept waiting for some data to receive in blocking mode, strange huh.

    Hope someone recognize this problem.

  8. #8
    Join Date
    May 2007
    Posts
    1,546

    Re: Socket Blocking Read TimeOut!

    Socket.Connected is useless. Check out the docs on it - it returns a stale cached value, not the current actual value.

    I use TimeOut because I run this piece of code in a seperate thread. To signal the thread that it has to close, I want to check, in the thread ofcourse, the signalstate periodically. So by using a timeout, I can get out off the blocking read and check the state and than try to read again.
    An alternative approach would be to keep a list of active sockets somewhere and when you want to terminate the thread, just call Socket.Close on the socket. A much better approach would be to use the async BeginRead/EndRead, BeginSend/EndSend methods so you don't have 1 thread per socket.

    I disconnected the socket while it was connected, but Socket.Read(...) didn't return with an exception or something it just kept waiting for some data to receive in blocking mode, strange huh.
    Check the docs on Socket.Read. It's documented to return '0' as the number of bytes read when the socket has been gracefully closed and *not* throw an exception. This is normal.
    www.monotorrent.com For all your .NET bittorrent needs

    NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.

  9. #9
    Join Date
    Jan 2007
    Posts
    102

    Re: Socket Blocking Read TimeOut!

    Mutant Fruit,

    Thnx for your respons.
    Check the docs on Socket.Read. It's documented to return '0' as the number of bytes read when the socket has been gracefully closed and *not* throw an exception. This is normal.
    This is not happening, it doesn't return with 0 bytes. I know this concept, cause that is what I do using C++ with win32 API. So though I call Socket.Disconnect(false/true); it seems not to come back from the Socket.Read().

    (Sorry, I just found out I used Socket.Disconnect() instead of Socket.Close().)

    A much better approach would be to use the async BeginRead/EndRead, BeginSend/EndSend methods so you don't have 1 thread per socket.
    The clue is, I want to use it in a GUI application. Using async BeginRead/EndRead still makes it not friendly as a class for a GUI. Because I have to call Mainthread.InvokeRequired to post the mainthread a message that some data has been received. While using backgroundworker class, we don't have that problem and the class much better to use for other programmers.
    Last edited by EmbeddedC; February 2nd, 2009 at 06:25 AM.

  10. #10
    Join Date
    Jan 2007
    Posts
    102

    Re: Socket Blocking Read TimeOut!

    Hello guys,

    Calling the Socket.Close() will do the trick as Mutant Fruit already said.
    This makes thus possible to complete my concept for writing a GUI friendly socket class.
    There are several ways to Rome (or for me to Tangiers) to achieve threadsafe networksocket for asynchronous send and receive in a GUI app.

    Anyway thank you very much for helping me.

  11. #11
    Join Date
    May 2007
    Posts
    1,546

    Re: Socket Blocking Read TimeOut!

    Quote Originally Posted by EmbeddedC View Post
    The clue is, I want to use it in a GUI application. Using async BeginRead/EndRead still makes it not friendly as a class for a GUI. Because I have to call Mainthread.InvokeRequired to post the mainthread a message that some data has been received. While using backgroundworker class, we don't have that problem and the class much better to use for other programmers.
    Yes and no.

    The 'yes' part:
    BackgroundWorker *slightly* simplifies how async operations can be safely used in a winforms application. All it does is call Mainthread.Invoke () for you when you raise the ProgressChanged and RunWorkerComplete events so that these events end up on the main loop. That's the only 'magic' it has.

    The 'no' part:
    You most definitely do *not* want to use 1 thread per socket in an application which makes heavy use of sockets. If you're only making a few connections (~5) then it's fine. If you're making 300 connections, it'd be horrible

    In either case, you can still use the async methods. There's no issue with using them as part of your background worker. Things will be pretty much exactly the same as what you have now, except that you'll be using BeginRead and EndRead instead of just "Read". If you're using the background worker correctly, things will work just fine.
    www.monotorrent.com For all your .NET bittorrent needs

    NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.

  12. #12
    Join Date
    Apr 2010
    Posts
    1

    Re: Socket Blocking Read TimeOut!

    I know this thread has been inactive a while but I found it so someone else may find this useful...

    I used the same logic (as the first post) and got the same problem. I did find though that resetting the socket mode to block after a WoudlBlock error code resolved this, ie:

    if (ex.SocketErrorCode == SocketError.WouldBlock)
    {
    sock.Blocking = true;
    continue;
    }

    It seems after this is done once the subsequent timeout errorcodes go back to being SocketError.TimedOut's

  13. #13
    Join Date
    Jun 2013
    Posts
    1

    Re: Socket Blocking Read TimeOut!

    Hello jive!
    I'm very happy you posted this.

    Quote Originally Posted by jive_b View Post
    I know this thread has been inactive a while but I found it so someone else may find this useful...

    I used the same logic (as the first post) and got the same problem. I did find though that resetting the socket mode to block after a WoudlBlock error code resolved this, ie:

    if (ex.SocketErrorCode == SocketError.WouldBlock)
    {
    sock.Blocking = true;
    continue;
    }

    It seems after this is done once the subsequent timeout errorcodes go back to being SocketError.TimedOut's
    [/QUOTE]
    It works, even if the property value is already true.
    If you catch the first SocketError.Timedout after a read, you can do it an get no more SocketError.WouldBlock

    It's a long time i've been looking for this. Thank you!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured