public void Start(Configuration config) { this._config = config; this._shareOverLAN = config.shareOverLan; if (CheckIfPortInUse(_config.localPort)) { throw new Exception(I18N.GetString("Port already in use")); } try { // Create a TCP/IP socket. _tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); _tcpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); _udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); IPEndPoint localEndPoint = null; localEndPoint = _shareOverLAN ? new IPEndPoint(IPAddress.Any, _config.localPort) : new IPEndPoint(IPAddress.Loopback, _config.localPort); // Bind the socket to the local endpoint and listen for incoming connections. _tcpSocket.Bind(localEndPoint); _udpSocket.Bind(localEndPoint); _tcpSocket.Listen(1024); // Start an asynchronous socket to listen for connections. Logging.Info($"Shadowsocks started ({UpdateChecker.Version})"); Logging.Info(Encryption.EncryptorFactory.DumpRegisteredEncryptor()); _tcpSocket.BeginAccept(new AsyncCallback(AcceptCallback), _tcpSocket); UDPState udpState = new UDPState(); udpState.socket = _udpSocket; _udpSocket.BeginReceiveFrom(udpState.buffer, 0, udpState.buffer.Length, 0, ref udpState.remoteEndPoint, new AsyncCallback(RecvFromCallback), udpState); } catch (SocketException) { _tcpSocket.Close(); throw; } }
public void RecvFromCallback(IAsyncResult ar) { UDPState state = (UDPState)ar.AsyncState; var socket = state.socket; try { int bytesRead = socket.EndReceiveFrom(ar, ref state.remoteEndPoint); foreach (IService service in _services) { if (service.Handle(state.buffer, bytesRead, socket, state)) { break; } } } catch (ObjectDisposedException) { } catch (Exception ex) { //Logging.Debug(ex); } finally { try { socket.BeginReceiveFrom(state.buffer, 0, state.buffer.Length, 0, ref state.remoteEndPoint, new AsyncCallback(RecvFromCallback), state); } catch (ObjectDisposedException) { // do nothing } catch (Exception) { } } }