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); }
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)); }
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))); } } }
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()); }