views:

457

answers:

5

My server/client start a new thread "readerThread()" for reading incoming tcp traffic. This thread blocks on read(). How can i exit this readerThread().

One way is to start another thread which closes the socket when the thread is to be exited so the read would exit. is there a more cleaner/better way to do it.

+1  A: 

If you're using a blocking read() command, you should almost always have another control thread that is in charge of shutting it down and cleaning up the socket.

Typically though, I would use a select() call that times out after 1 second or so to test if there is data to be read, and each timeout cycle checks if a shutdown status flag has been set by another thread.

But if you go with pure blocking, use a control thread as you suggest.

Walt W
like select() with timeout in unix network programming? do u have any examples of doing it in c#
Kazoom
Alternatively, just use non-blocking I/O and check for status whenever the function call returns.
Matthew Iselin
If it's a simple program, Matthew's suggestion is a good idea. I don't have any examples in C# at the moment though. But yeah, like select(). There should even be a select call in C#. . . select's not only a unix command, it's in windows as well.
Walt W
select() equivalent: System.Net.Sockets.Socket.Select. Better choice would be System.Net.Sockets.Socket.Poll though.
Matthew Iselin
+1  A: 

I would use Asnyncronous Socket communication. I wrote an article which demos this on my blog. ou can read here:

http://www.andrewrea.co.uk/blog/2009/06/09/Part1SocketProgrammingWithCJAVACAndActionScript30EstablishingABaseConnectionAndCommunicationWithCServerAndAS3.aspx

Andrew

REA_ANDREW
A: 

Another way to do it is to send a 0 byte packet to your listening socket from somewhere else in your own application when you want to shut it down.

I've found that's a slightly cleaner approach than closing the coket from another thread since an exception will be thrown by the listening thread if you close the socket on it.

sipwiz
A: 

I'm somewhat puzzled what exactly you are doing: there is no read() method for the Socket class in .NET.

My recommendation is to create a second socket, which is listening on a specific port, and have the thread block in Socket.Select instead. Connecting to that second socket should be taken as a shutdown request (perhaps after proper authentication, e.g. by sending an application password over that socket).

Martin v. Löwis
+2  A: 

I misunderstood the question. Here is what I think you should do.

  • If you created the socket in parent thread, and only use the new thread to read incoming data, then I would suggest calling Socket.Shutdown().This way the Receive methods will return 0 (no bytes read), and you can exit from thread's method. Shutdown will disable send/receive, but if there is any data in buffer that is waiting to be sent/received it will ensure that it is sent/received before closing the socket. Your Receive method will return 0 if you call shutdown while the socket is blocked on Receive, but it will throw a socket exception with Socket error code = Shutdown (or 10058). So be ready to catch and handle it.

  • If you create the socket in new thread, and its accepting new connections (Socket.Listen() and Socket.Accept) then you can connect with that socket from your parent thread and Send 0 bytes. You can exit new thread when Receive methods returns 0 bytes.

  • If you are creating the socket in new thread, and it can only a client (Connects with other socket) then this is not a good approach at all. You may have to Abort the thread (not recommended), unless you configure your server to send 0 bytes when you want your client socket to close, but this way your client app will be dependent on server for closing the socket.

cornerback84