예제 #1
0
        public ValueTask <ConnectionContext> Connect(IPEndPoint endpoint)
        {
            var         domain = endpoint.AddressFamily == AddressFamily.InterNetwork ? AF_INET : AF_INET6;
            LinuxSocket s      = socket(domain, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP);

            if (_threadContext.Options.TcpNoDelay)
            {
                s.SetOption(SOL_TCP, TCP_NODELAY, 1);
            }

            var context = new OutboundConnectionContext(s, endpoint, _threadContext);
            var tcs     = new TaskCompletionSource <ConnectionContext>(TaskCreationOptions.RunContinuationsAsynchronously); // Ensure the transport thread doesn't run continuations

            context.ConnectCompletion = tcs;

            endpoint.ToSockAddr(context.Addr, out var addrLength);
            context.AddrLen = addrLength;

            _connections[s] = context;
            Connect(context);

            _threadContext.Notify();

            return(new ValueTask <ConnectionContext>(tcs.Task));
        }
예제 #2
0
        public ValueTask <ConnectionContext> Connect(IPEndPoint endpoint)
        {
            var         domain = endpoint.AddressFamily == AddressFamily.InterNetwork ? AF_INET : AF_INET6;
            LinuxSocket s      = socket(domain, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP);

            if (_threadContext.Options.TcpNoDelay)
            {
                s.SetOption(SOL_TCP, TCP_NODELAY, 1);
            }
            var context = new OutboundConnectionContext(s, endpoint, _threadContext);

            bool connectedSynchronously;

            try
            {
                connectedSynchronously = s.TryConnectNonBlocking(endpoint);
            }
            catch (ErrnoException ex)
            {
                return(new ValueTask <ConnectionContext>(Task.FromException <ConnectionContext>(ex)));
            }

            if (connectedSynchronously)
            {
                context.LocalEndPoint = s.GetLocalAddress();
                return(new ValueTask <ConnectionContext>(context));
            }

            var tcs = new TaskCompletionSource <ConnectionContext>();

            context.ConnectCompletion = tcs;

            // Socket will become writable, once connect completed
            _clientSocketQueue.Enqueue(context);
            _threadContext.Notify();

            return(new ValueTask <ConnectionContext>(tcs.Task));
        }