简体   繁体   中英

Exiting a thread blocking on TCP read in C#

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.

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.

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.

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

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, eg by sending an application password over that socket).

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM