private readonly IPEndPoint _localEndPoint;
private Thread listenThread;
private SocketRequestHandler _requestHandler;
+ private bool _stopped = true;
+ private readonly object _syncRoot = new object ();
+
+ private const int SOCKET_CLOSED = 10004;
+ private const int SOCKET_INVALID_ARGS = 10022;
public SocketResponder (IPEndPoint localEP, SocketRequestHandler requestHandler)
{
Stop ();
}
+ public bool IsStopped
+ {
+ get
+ {
+ lock (_syncRoot) {
+ return _stopped;
+ }
+ }
+ }
+
public void Start ()
{
- tcpListener = new TcpListener (LocalEndPoint);
- tcpListener.Start ();
- listenThread = new Thread (new ThreadStart (Listen));
- listenThread.Start ();
+ lock (_syncRoot) {
+ if (!_stopped)
+ return;
+ _stopped = false;
+ tcpListener = new TcpListener (LocalEndPoint);
+ tcpListener.Start ();
+ listenThread = new Thread (new ThreadStart (Listen));
+ listenThread.Start ();
+ }
}
public void Stop ()
{
- if (tcpListener != null)
- tcpListener.Stop ();
-
- try {
- if (listenThread != null && listenThread.ThreadState == ThreadState.Running) {
- listenThread.Abort ();
+ lock (_syncRoot) {
+ if (_stopped)
+ return;
+ _stopped = true;
+ if (tcpListener != null) {
+ tcpListener.Stop ();
+ tcpListener = null;
+ Thread.Sleep (50);
}
- } catch {
}
}
private void Listen ()
{
- Socket socket = tcpListener.AcceptSocket ();
- socket.Send (_requestHandler (socket));
+ while (!_stopped) {
+ Socket socket = null;
+ try {
+ socket = tcpListener.AcceptSocket ();
+ socket.Send (_requestHandler (socket));
+ try {
+ socket.Shutdown (SocketShutdown.Receive);
+ socket.Shutdown (SocketShutdown.Send);
+ } catch {
+ }
+ } catch (SocketException ex) {
+ // ignore interruption of blocking call
+ if (ex.ErrorCode != SOCKET_CLOSED && ex.ErrorCode != SOCKET_INVALID_ARGS)
+ throw;
+ } finally {
+ Thread.Sleep (500);
+ if (socket != null)
+ socket.Close ();
+ }
+ }
}
}
}