예제 #1
0
        public void Complete(Exception exception, int transferred)
        {
            Debug.Assert(_overlapped != null);

            RegisteredSocket socket = _socket;

            _socket = null;
            _buffersHandle.Free();

            _boundHandle.FreeNativeOverlapped(_overlapped);
            _boundHandle   = null;
            _overlapped    = null;
            _thisRef.Value = null;

            if (exception == null)
            {
                _valueTaskSource.SetResult(transferred);
            }
            else
            {
                _valueTaskSource.SetException(exception);
            }

            Interlocked.Exchange(ref _isSend ? ref socket._cachedSendArgs : ref socket._cachedRecvArgs, this);
        }
예제 #2
0
        public (ValueTask <int>, IntPtr thisPtr, IntPtr buffersPtr) Prepare(RegisteredSocket socket, bool isSend, ReadOnlySpan <Memory <byte> > buffers)
        {
            if (_overlapped != null)
            {
                throw new InvalidOperationException();
            }

            SetBuffers(buffers);
            return(Prepare(socket, isSend));
        }
예제 #3
0
        static async Task Main(string[] args)
        {
            using Socket socket = RegisteredSocket.CreateRegisterableSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            await socket.ConnectAsync(new DnsEndPoint("microsoft.com", 80));

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

            using var bufferPool       = new RegisteredMemoryPool();
            using var multiplexer      = new RegisteredMultiplexer(queueSize: 10);
            using var registeredSocket = new RegisteredSocket(multiplexer, socket);

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

            async Task DoSend()
            {
                Memory <byte> sendBuffer = bufferPool.Rent(64).Memory;
                int           bytes      = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost: microsoft.com\r\n\r\n", sendBuffer.Span);

                sendBuffer = sendBuffer.Slice(bytes);

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

                    if (bytesSent == 0)
                    {
                        break;
                    }

                    sendBuffer = sendBuffer.Slice(bytesSent);
                }
            }

            async Task DoReceive()
            {
                Memory <byte> recvBuffer = bufferPool.Rent(4096).Memory;

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

                    if (bytesReceived == 0)
                    {
                        break;
                    }

                    Console.WriteLine(Encoding.ASCII.GetString(recvBuffer.Span.Slice(bytesReceived)));
                }
            }
        }
예제 #4
0
        private (ValueTask <int>, IntPtr thisPtr, IntPtr buffersPtr) Prepare(RegisteredSocket socket, bool isSend)
        {
            _socket        = socket;
            _isSend        = isSend;
            _buffersHandle = GCHandle.Alloc(_buffers, GCHandleType.Pinned);
            _valueTaskSource.Reset();

            _boundHandle   = GetOrAllocateThreadPoolBoundHandle(socket._socket);
            _thisRef.Value = this;
            _overlapped    = _boundHandle.AllocateNativeOverlapped(_preallocatedOverlapped);

            ValueTask <int> task = new ValueTask <int>(this, _valueTaskSource.Version);

            return(task, new IntPtr(_overlapped), _buffersHandle.AddrOfPinnedObject());
        }