//
-// SocketResponsder.cs - Utility class for tests that require a listener
+// SocketResponder.cs - Utility class for tests that require a listener
//
// Author:
// Gert Driesen (drieseng@users.sourceforge.net)
using System.Text;
using System.Threading;
-public delegate byte[] SocketRequestHandler (Socket socket);
-
-public class SocketResponder : IDisposable
+namespace MonoTests.System.Net
{
- private TcpListener tcpListener;
- private readonly IPEndPoint _localEndPoint;
- private Thread listenThread;
- private SocketRequestHandler _requestHandler;
+ public delegate byte [] SocketRequestHandler (Socket socket);
- public SocketResponder (IPEndPoint localEP, SocketRequestHandler requestHandler)
+ public class SocketResponder : IDisposable
{
- _localEndPoint = localEP;
- _requestHandler = requestHandler;
- }
+ private TcpListener tcpListener;
+ private readonly IPEndPoint _localEndPoint;
+ private Thread listenThread;
+ private SocketRequestHandler _requestHandler;
+ private bool _stopped = true;
+ private readonly object _syncRoot = new object ();
- public IPEndPoint LocalEndPoint
- {
- get { return _localEndPoint; }
- }
+ private const int SOCKET_CLOSED = 10004;
- public void Dispose ()
- {
- Stop ();
- }
+ public SocketResponder (IPEndPoint localEP, SocketRequestHandler requestHandler)
+ {
+ _localEndPoint = localEP;
+ _requestHandler = requestHandler;
+ }
- public void Start ()
- {
- tcpListener = new TcpListener (LocalEndPoint);
- tcpListener.Start ();
- listenThread = new Thread (new ThreadStart (Listen));
- listenThread.Start ();
- }
+ public IPEndPoint LocalEndPoint
+ {
+ get { return _localEndPoint; }
+ }
- public void Stop ()
- {
- if (tcpListener != null)
- tcpListener.Stop ();
+ public void Dispose ()
+ {
+ Stop ();
+ }
- try {
- if (listenThread != null && listenThread.ThreadState == ThreadState.Running) {
- listenThread.Abort ();
+ public bool IsStopped
+ {
+ get
+ {
+ lock (_syncRoot) {
+ return _stopped;
+ }
}
- } catch {
}
- }
- private void Listen ()
- {
- Socket socket = tcpListener.AcceptSocket ();
- socket.Send(_requestHandler(socket));
+ public void Start ()
+ {
+ lock (_syncRoot) {
+ if (!_stopped)
+ return;
+ _stopped = false;
+ listenThread = new Thread (new ThreadStart (Listen));
+ listenThread.Start ();
+ Thread.Sleep (20); // allow listener to start
+ }
+ }
+
+ public void Stop ()
+ {
+ lock (_syncRoot) {
+ if (_stopped)
+ return;
+ _stopped = true;
+ if (tcpListener != null) {
+ tcpListener.Stop ();
+ tcpListener = null;
+ }
+ }
+ }
+
+ private void Listen ()
+ {
+ tcpListener = new TcpListener (LocalEndPoint);
+ tcpListener.Start ();
+ while (!_stopped) {
+ try {
+ Socket socket = tcpListener.AcceptSocket ();
+ socket.Send (_requestHandler (socket));
+ socket.Shutdown (SocketShutdown.Send);
+ Thread.Sleep (500);
+ socket.Close ();
+ } catch (SocketException ex) {
+ // ignore interruption of blocking call
+ if (ex.ErrorCode != SOCKET_CLOSED)
+ throw;
+ }
+ }
+ }
}
}