public Socket ConnectTo() { if (_unixSocketPath != null) { var client = Socket.Create(AF_UNIX, SOCK_STREAM, 0, blocking: true); client.Connect(_unixSocketPath); return(client); } else if (_serverAddress != null) { var client = Socket.Create(AF_INET, SOCK_STREAM, IPPROTO_TCP, blocking: true); client.SetSocketOption(SOL_TCP, TCP_NODELAY, 1); client.Connect(_serverAddress); return(client); } else { return(null); } }
public async Task BindAsync() { AcceptThread acceptThread; TransportThread[] transportThreads; lock (_gate) { if (_state != State.Created) { ThrowInvalidOperation(); } _state = State.Binding; switch (EndPoint) { case IPEndPoint ipEndPoint: acceptThread = null; transportThreads = CreateTransportThreads(ipEndPoint, acceptThread: null); break; case UnixDomainSocketEndPoint unixDomainSocketEndPoint: var socketPath = unixDomainSocketEndPoint.ToString(); var unixDomainSocket = Socket.Create(AF_UNIX, SOCK_STREAM, 0, blocking: false); File.Delete(socketPath); unixDomainSocket.Bind(socketPath); unixDomainSocket.Listen(ListenBacklog); acceptThread = new AcceptThread(unixDomainSocket); transportThreads = CreateTransportThreads(ipEndPoint: null, acceptThread); break; case FileHandleEndPoint fileHandleEndPoint: var fileHandleSocket = new Socket((int)fileHandleEndPoint.FileHandle); acceptThread = new AcceptThread(fileHandleSocket); transportThreads = CreateTransportThreads(ipEndPoint: null, acceptThread); break; default: throw new NotSupportedException($"Unknown ListenType: {EndPoint.GetType()}."); } _threads = new ITransportActionHandler[transportThreads.Length + (acceptThread != null ? 1 : 0)]; _threads[0] = acceptThread; for (int i = 0; i < transportThreads.Length; i++) { _threads[i + (acceptThread == null ? 0 : 1)] = transportThreads[i]; } _logger.LogDebug($@"BindAsync {EndPoint}: TC:{_transportOptions.ThreadCount} TA:{_transportOptions.SetThreadAffinity} IC:{_transportOptions.ReceiveOnIncomingCpu} DA:{_transportOptions.DeferAccept}"); } var tasks = new Task[transportThreads.Length]; for (int i = 0; i < transportThreads.Length; i++) { tasks[i] = transportThreads[i].BindAsync(); } try { await Task.WhenAll(tasks); if (acceptThread != null) { await acceptThread.BindAsync(); } _acceptEnumerator = AcceptConnections(); lock (_gate) { if (_state == State.Binding) { _state = State.Bound; } else { ThrowInvalidOperation(); } } } catch { await DisposeAsync(); throw; } }
public async Task BindAsync() { AcceptThread acceptThread; TransportThread[] transportThreads; lock (_gate) { if (_state != State.Created) { ThrowInvalidOperation(); } _state = State.Binding; IPEndPoint ipEndPoint; switch (_endPoint.Type) { case ListenType.IPEndPoint: ipEndPoint = _endPoint.IPEndPoint; acceptThread = null; transportThreads = CreateTransportThreads(ipEndPoint, acceptThread); break; case ListenType.SocketPath: case ListenType.FileHandle: Socket socket; if (_endPoint.Type == ListenType.SocketPath) { socket = Socket.Create(AF_UNIX, SOCK_STREAM, 0, blocking: false); File.Delete(_endPoint.SocketPath); socket.Bind(_endPoint.SocketPath); socket.Listen(ListenBacklog); } else { socket = new Socket((int)_endPoint.FileHandle); } ipEndPoint = null; acceptThread = new AcceptThread(socket); transportThreads = CreateTransportThreads(ipEndPoint, acceptThread); break; default: throw new NotSupportedException($"Unknown ListenType: {_endPoint.Type}."); } _threads = new ITransportActionHandler[transportThreads.Length + (acceptThread != null ? 1 : 0)]; _threads[0] = acceptThread; for (int i = 0; i < transportThreads.Length; i++) { _threads[i + (acceptThread == null ? 0 : 1)] = transportThreads[i]; } _logger.LogDebug($@"BindAsync {_endPoint}: TC:{_transportOptions.ThreadCount} TA:{_transportOptions.SetThreadAffinity} IC:{_transportOptions.ReceiveOnIncomingCpu} DA:{_transportOptions.DeferAccept}"); } var tasks = new Task[transportThreads.Length]; for (int i = 0; i < transportThreads.Length; i++) { tasks[i] = transportThreads[i].BindAsync(); } try { await Task.WhenAll(tasks); if (acceptThread != null) { await acceptThread.BindAsync(); } lock (_gate) { if (_state == State.Binding) { _state = State.Bound; } else { ThrowInvalidOperation(); } } } catch { await StopAsync(); throw; } }