How do I kill or break out of a synchronous Socket.Accept() call?

G

Guest

I'm trying to implement a simple server in C#. I want to do the classic thing of spinning off a thread that just blocks in a Socket.Accept() call until a request comes in. At that point, the Accept() returns, the thread spins off another thread to handle the request, and then calls Accept() again.

This all works fine except that I can find no way to kill the thread that is blocked in the Accept() call when I want to shut down the server. If I call Thread.Abort() on that thread, the thread does not abort. I know this because if I do a Thread.Join() after the Thread.Abort() on the thread, my main thread blocks in the Thread.Join() call. If I don't call Thread.Join(), then my app hangs later on when trying to exit, and so never exits.

I can switch to using a non-blocking Accept(), but I'd rather do the classic (and, IMHO, correct) way.

Anyone know why I can't kill a thread that is locked in a Socket.Accept() call? Any ideas as to how to cause the Accept() to exit?

TIA,

Blatwurst
 
J

Jon Skeet [C# MVP]

Blatwurst said:
I'm trying to implement a simple server in C#. I want to do the
classic thing of spinning off a thread that just blocks in a
Socket.Accept() call until a request comes in. At that point, the
Accept() returns, the thread spins off another thread to handle the
request, and then calls Accept() again.

This all works fine except that I can find no way to kill the thread
that is blocked in the Accept() call when I want to shut down the
server. If I call Thread.Abort() on that thread, the thread does not
abort. I know this because if I do a Thread.Join() after the
Thread.Abort() on the thread, my main thread blocks in the
Thread.Join() call. If I don't call Thread.Join(), then my app hangs
later on when trying to exit, and so never exits.

I can switch to using a non-blocking Accept(), but I'd rather do the
classic (and, IMHO, correct) way.

Anyone know why I can't kill a thread that is locked in a
Socket.Accept() call? Any ideas as to how to cause the Accept() to
exit?

Have you tried calling Close, Dispose or Shutdown on the socket from
the other thread?
 
G

Guest

Hi Jon, Thanks for the reply.

I've tried calling both Close() and/or Shutdown(). Socket doesn't have a Dispose(), or I would have tried that too. I also tried setting the Blocking property to false. Nothing I do will cause Accept() to either return or throw an exception.
 
S

Sunny

Hi,
if your problem is just that the app does not exit, make the thread
which blocks on Accept() as background thread. This way this thread will
be killed on application exit.

Not the best solution, but is should work.

Sunny
 
G

Guest

Thanks Sunny,

Yes, not ideal, but that should help in this case. That thread should have been a background thread anyway. Thanks for the help.
 
J

Jon Skeet [C# MVP]

Blatwurst said:
I've tried calling both Close() and/or Shutdown(). Socket doesn't
have a Dispose(), or I would have tried that too. I also tried
setting the Blocking property to false. Nothing I do will cause
Accept() to either return or throw an exception.

Socket *does* have a Dispose method, you just need to cast it to
IDisposable first.

Do you have a small test app you're using to check this? If so, it
would be helpful if you could post it so I could try a few things.

Calling Close seems to work for me - the call to Accept throws a
SocketException. Here's my sample app:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

class Test
{
static Socket skt;

static void Main()
{
skt = new Socket
(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.IP);

EndPoint endPoint = new IPEndPoint(IPAddress.Any, 12345);
skt.Bind(endPoint);
skt.Listen(10);

new Thread (new ThreadStart(StopMe)).Start();
skt.Accept();
}

static void StopMe()
{
Thread.Sleep(1000);
Console.WriteLine("Stopping");
skt.Close();
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top