public RegisteredSocketConnection(RegisteredMemoryPool memoryPool, RegisteredSocket socket, long?maxReadBufferSize, long?maxWriteBufferSize)
        {
            _features.Add(typeof(IConnectionIdFeature), this);
            _features.Add(typeof(IConnectionTransportFeature), this);
            _features.Add(typeof(IConnectionItemsFeature), this);
            _features.Add(typeof(IMemoryPoolFeature), this);
            _features.Add(typeof(IConnectionLifetimeFeature), this);

            _socket          = socket;
            ConnectionClosed = _cancellationTokenSource.Token;
            LocalEndPoint    = socket.LocalEndPoint;
            RemoteEndPoint   = socket.RemoteEndPoint;

            var inputPipeOptions = new PipeOptions(pool: memoryPool, pauseWriterThreshold: maxReadBufferSize.GetValueOrDefault(), resumeWriterThreshold: maxReadBufferSize.GetValueOrDefault() / 2, useSynchronizationContext: false);
            var inputPipe        = new Pipe(inputPipeOptions);

            var outputPipeOptions = new PipeOptions(pool: memoryPool, pauseWriterThreshold: maxWriteBufferSize.GetValueOrDefault(), resumeWriterThreshold: maxWriteBufferSize.GetValueOrDefault() / 2, useSynchronizationContext: false);
            var outputPipe        = new Pipe(outputPipeOptions);

            (_transportInput, _transportOutput) = (inputPipe.Reader, outputPipe.Writer);
            (_socketInput, _socketOutput)       = (outputPipe.Reader, inputPipe.Writer);
            Transport = this;

            _ioTask = Task.WhenAll(DoReceiveAsync(), DoSendAsync());
        }
Пример #2
0
        static async Task Main(string[] args)
        {
            using var bufferPool  = new RegisteredMemoryPool();
            using var multiplexer = new RegisteredMultiplexer();
            int clientIds = 0;

            await Task.WhenAll(RunOneClient(), RunOneClient(), RunOneClient(), RunOneClient(), RunOneClient()).ConfigureAwait(false);

            async Task RunOneClient()
            {
                int clientId = Interlocked.Increment(ref clientIds);

                using var socket = new RegisteredSocket(multiplexer, AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                await socket.ConnectAsync(new DnsEndPoint("microsoft.com", 80));

                Console.WriteLine($"{clientId}: connected ({socket.LocalEndPoint} -> {socket.RemoteEndPoint}).");

                await Task.WhenAll(DoSend(), DoReceive()).ConfigureAwait(false);

                Console.WriteLine($"{clientId}: done.");

                async Task DoSend()
                {
                    Console.WriteLine($"{clientId}: sending...");

                    var operationContext = socket.CreateOperationContext();

                    using IMemoryOwner <byte> sendBufferOwner = bufferPool.Rent(128);
                    Memory <byte> sendBuffer = sendBufferOwner.Memory;

                    int bytes = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost: microsoft.com\r\nConnection: close\r\n\r\n", sendBuffer.Span);

                    sendBuffer = sendBuffer.Slice(0, bytes);

                    while (sendBuffer.Length != 0)
                    {
                        int bytesSent = await operationContext.SendAsync(sendBuffer).ConfigureAwait(false);

                        Console.WriteLine($"{clientId}: sent {bytesSent:N0} bytes.");

                        if (bytesSent == 0)
                        {
                            break;
                        }

                        sendBuffer = sendBuffer.Slice(bytesSent);
                    }

                    Console.WriteLine($"{clientId}: done sending.");
                    socket.Shutdown(SocketShutdown.Send);
                }

                async Task DoReceive()
                {
                    Console.WriteLine($"{clientId}: receiving...");

                    var operationContext = socket.CreateOperationContext();

                    using IMemoryOwner <byte> recvBufferOwner = bufferPool.Rent(4096);
                    Memory <byte> recvBuffer = recvBufferOwner.Memory;

                    while (true)
                    {
                        int bytesReceived = await operationContext.ReceiveAsync(recvBuffer).ConfigureAwait(false);

                        Console.WriteLine($"{clientId}: received {bytesReceived:N0} bytes.");

                        if (bytesReceived == 0)
                        {
                            break;
                        }
                    }

                    Console.WriteLine($"{clientId}: done receiving.");
                }
            }
        }