internal void Start() { if (-1 == _port) { return; } try { IPAddress addr = IPAddress.Loopback; _listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); #if (DEBUG) // Check an option that provides for listening on all the network interfaces, not only loopback (DEBUG builds only) if (!Core.SettingStore.ReadBool("RemoteControl", "LoopbackInterfaceOnly", true)) { addr = IPAddress.Any; } #endif if (_port != 0) { _listenSocket.Bind(new IPEndPoint(addr, _port)); } else { _storePort = true; while (true) { _port = generateRandomPort(); try { _listenSocket.Bind(new IPEndPoint(IPAddress.Loopback, _port)); break; } catch (SocketException ex) { if (ex.ErrorCode != 10048) // WSAEADDRINUSE { return; } } } } _listenSocket.Listen((int)SocketOptionName.MaxConnections); _stop = Winsock.WSACreateEvent(); Winsock.WSAResetEvent(_stop); _mainThread = new Thread(new ThreadStart(Listener)); _mainThread.Name = _threadName; _mainThread.Start(); _mainThread.Priority = ThreadPriority.BelowNormal; } catch { Winsock.WSASetEvent(_stop); _port = -1; throw; } return; }
private void Listener() { IntPtr socketEvent = Winsock.WSACreateEvent(); IntPtr[] allEvents = { _stop, socketEvent }; IntPtr handle = _listenSocket.Handle; Winsock.WSAEventSelect(handle, socketEvent, Winsock.FD_ACCEPT); while (true) { try { uint res = Winsock.WSAWaitForMultipleEvents(2, allEvents, 0 /*false*/, Winsock.WSA_INFINITE, 1 /*true*/); if (res == Winsock.WSA_WAIT_EVENT_0) { Trace.WriteLine("[RCS] Event 0 (STOP) signalled"); break; } else if (res == Winsock.WSA_WAIT_EVENT_0 + 1) { Winsock.WSAResetEvent(socketEvent); Trace.WriteLine("[RCS] Event 1 (ACCEPT) signalled"); Socket cs = _listenSocket.Accept(); Winsock.WSAEventSelect(cs.Handle, socketEvent, 0); cs.Blocking = true; Trace.WriteLine("[RCS] Client accepted at socket " + cs.Handle.ToString()); ThreadPool.QueueUserWorkItem(_onAccept, cs); } else { Trace.WriteLine("[RCS] Event " + res.ToString() + " (?) signalled"); } } catch (Exception ex) { Trace.WriteLine("[RCS] Accept exception: " + ex.Message); // If not sopped: sleep and try again if (Winsock.WSAWaitForMultipleEvents(1, new IntPtr[] { _stop }, 1 /*true*/, 0, 0 /*false*/) != Winsock.WSA_WAIT_EVENT_0) { Trace.WriteLine("[RCS] It is not stop!"); Thread.Sleep(100); } else { Trace.WriteLine("[RCS] It is stop, exiting."); // Stopped: exit break; } } } try { Trace.WriteLine("[RCS] Closing main socket " + handle.ToString() + " ..."); _listenSocket.Close(); Trace.WriteLine("[RCS] Main socket " + handle.ToString() + " closed."); } catch (Exception ex) { Trace.WriteLine("[RCS] Main socket closing exception: " + ex.Message); } finally { _listenSocket = null; } Winsock.WSACloseEvent(socketEvent); }