Exemplo n.º 1
0
        /// <inheritdoc />
        /// <exception cref="ArgumentNullException">When <paramref name="endPoint"/> is <see langword="null"/>.</exception>
        public override async ValueTask <Connection> ConnectAsync(
            EndPoint?endPoint,
            IConnectionProperties?options       = null,
            CancellationToken cancellationToken = default)
        {
            if (endPoint == null)
            {
                throw new ArgumentNullException(nameof(endPoint));
            }
            cancellationToken.ThrowIfCancellationRequested();

            Socket socket = CreateSocket(_addressFamily, _socketType, _protocolType, endPoint, options);

            try
            {
                await socket.ConnectAsync(endPoint, cancellationToken).ConfigureAwait(false);

                return(new SocketConnection(socket));
            }
            catch (SocketException socketException)
            {
                socket.Dispose();
                throw NetworkErrorHelper.MapSocketException(socketException);
            }
            catch
            {
                socket.Dispose();
                throw;
            }
        }
Exemplo n.º 2
0
        public override ValueTask <int> ReadAsync(Memory <byte> buffer, CancellationToken cancellationToken)
        {
            bool canRead = CanRead; // Prevent race with Dispose.

            ThrowIfDisposed();
            if (!canRead)
            {
                throw new InvalidOperationException(SR.net_writeonlystream);
            }

            try
            {
                return(_streamSocket.ReceiveAsync(
                           buffer,
                           SocketFlags.None,
                           fromNetworkStream: true,
                           cancellationToken: cancellationToken));
            }
            catch (SocketException socketException)
            {
                throw NetworkErrorHelper.MapSocketException(socketException);
            }
            catch (Exception exception) when(!(exception is OutOfMemoryException))
            {
                throw GetCustomNetworkException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
            }
        }
Exemplo n.º 3
0
        public override ValueTask WriteAsync(ReadOnlyMemory <byte> buffer, CancellationToken cancellationToken)
        {
            bool canWrite = CanWrite; // Prevent race with Dispose.

            ThrowIfDisposed();
            if (!canWrite)
            {
                throw new InvalidOperationException(SR.net_readonlystream);
            }

            try
            {
                return(_streamSocket.SendAsyncForNetworkStream(
                           buffer,
                           SocketFlags.None,
                           cancellationToken));
            }
            catch (SocketException socketException)
            {
                throw NetworkErrorHelper.MapSocketException(socketException);
            }
            catch (Exception exception) when(!(exception is OutOfMemoryException))
            {
                throw GetCustomNetworkException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
            }
        }
Exemplo n.º 4
0
        public override int Read(Span <byte> buffer)
        {
            if (GetType() != typeof(NetworkStream))
            {
                // NetworkStream is not sealed, and a derived type may have overridden Read(byte[], int, int) prior
                // to this Read(Span<byte>) overload being introduced.  In that case, this Read(Span<byte>) overload
                // should use the behavior of Read(byte[],int,int) overload.
                return(base.Read(buffer));
            }

            ThrowIfDisposed();
            if (!CanRead)
            {
                throw new InvalidOperationException(SR.net_writeonlystream);
            }

            int bytesRead = _streamSocket.Receive(buffer, SocketFlags.None, out SocketError errorCode);

            if (errorCode != SocketError.Success)
            {
                var exception = new SocketException((int)errorCode);
                throw NetworkErrorHelper.MapSocketException(exception);
            }
            return(bytesRead);
        }
        /// <summary>
        /// Establishes a new connection for a request.
        /// </summary>
        /// <param name="message">The request causing this connection to be established. Once connected, it may be reused for many subsequent requests.</param>
        /// <param name="endPoint">The EndPoint to connect to.</param>
        /// <param name="options">Properties, if any, that might change how the connection is made.</param>
        /// <param name="cancellationToken">A cancellation token for the asynchronous operation.</param>
        /// <returns>A new open connection.</returns>
        public virtual async ValueTask <Connection> EstablishConnectionAsync(HttpRequestMessage message, EndPoint?endPoint, IConnectionProperties options, CancellationToken cancellationToken)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }
            if (endPoint == null)
            {
                throw new ArgumentNullException(nameof(endPoint));
            }

            Socket socket = CreateSocket(message, endPoint, options);

            try
            {
                using var args      = new TaskSocketAsyncEventArgs();
                args.RemoteEndPoint = endPoint;

                if (socket.ConnectAsync(args))
                {
                    using (cancellationToken.UnsafeRegister(o => Socket.CancelConnectAsync((SocketAsyncEventArgs)o !), args))
                    {
                        await args.Task.ConfigureAwait(false);
                    }
                }

                if (args.SocketError != SocketError.Success)
                {
                    Exception ex = args.SocketError == SocketError.OperationAborted && cancellationToken.IsCancellationRequested
                        ? (Exception) new OperationCanceledException(cancellationToken)
                        : new SocketException((int)args.SocketError);

                    throw ex;
                }

                socket.NoDelay = true;
                return(new SocketConnection(socket));
            }
            catch (SocketException socketException)
            {
                socket.Dispose();
                throw NetworkErrorHelper.MapSocketException(socketException);
            }
            catch
            {
                socket.Dispose();
                throw;
            }
        }
Exemplo n.º 6
0
        // BeginWrite - provide async write functionality.
        //
        // This method provides async write functionality. All we do is
        // call through to the underlying socket async send.
        //
        // Input:
        //
        //     buffer  - Buffer to write into.
        //     offset  - Offset into the buffer where we're to write.
        //     size   - Number of bytes to written.
        //
        // Returns:
        //
        //     An IASyncResult, representing the write.
        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback?callback, object?state)
        {
            bool canWrite = CanWrite; // Prevent race with Dispose.

            ThrowIfDisposed();
            if (!canWrite)
            {
                throw new InvalidOperationException(SR.net_readonlystream);
            }

            // Validate input parameters.
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            if ((uint)offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }
            if ((uint)size > buffer.Length - offset)
            {
                throw new ArgumentOutOfRangeException(nameof(size));
            }

            try
            {
                // Call BeginSend on the Socket.
                return(_streamSocket.BeginSend(
                           buffer,
                           offset,
                           size,
                           SocketFlags.None,
                           callback,
                           state));
            }
            catch (SocketException socketException)
            {
                throw NetworkErrorHelper.MapSocketException(socketException);
            }
            catch (Exception exception) when(!(exception is OutOfMemoryException))
            {
                throw GetCustomNetworkException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
            }
        }
Exemplo n.º 7
0
        // ReadAsync - provide async read functionality.
        //
        // This method provides async read functionality. All we do is
        // call through to the Begin/EndRead methods.
        //
        // Input:
        //
        //     buffer            - Buffer to read into.
        //     offset            - Offset into the buffer where we're to read.
        //     size              - Number of bytes to read.
        //     cancellationToken - Token used to request cancellation of the operation
        //
        // Returns:
        //
        //     A Task<int> representing the read.
        public override Task <int> ReadAsync(byte[] buffer, int offset, int size, CancellationToken cancellationToken)
        {
            bool canRead = CanRead; // Prevent race with Dispose.

            ThrowIfDisposed();
            if (!canRead)
            {
                throw new InvalidOperationException(SR.net_writeonlystream);
            }

            // Validate input parameters.
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            if ((uint)offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }
            if ((uint)size > buffer.Length - offset)
            {
                throw new ArgumentOutOfRangeException(nameof(size));
            }

            try
            {
                return(_streamSocket.ReceiveAsync(
                           new Memory <byte>(buffer, offset, size),
                           SocketFlags.None,
                           fromNetworkStream: true,
                           cancellationToken).AsTask());
            }
            catch (SocketException socketException)
            {
                throw NetworkErrorHelper.MapSocketException(socketException);
            }
            catch (Exception exception) when(!(exception is OutOfMemoryException))
            {
                throw GetCustomNetworkException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
            }
        }
Exemplo n.º 8
0
        // Write - provide core Write functionality.
        //
        // Provide core write functionality. All we do is call through to the
        // socket Send method..
        //
        // Input:
        //
        //     Buffer  - Buffer to write from.
        //     Offset  - Offset into the buffer from where we'll start writing.
        //     Count   - Number of bytes to write.
        //
        // Returns:
        //
        //     Number of bytes written. We'll throw an exception if we
        //     can't write everything. It's brutal, but there's no other
        //     way to indicate an error.
        public override void Write(byte[] buffer, int offset, int size)
        {
            bool canWrite = CanWrite; // Prevent race with Dispose.

            ThrowIfDisposed();
            if (!canWrite)
            {
                throw new InvalidOperationException(SR.net_readonlystream);
            }

            // Validate input parameters.
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            if ((uint)offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }
            if ((uint)size > buffer.Length - offset)
            {
                throw new ArgumentOutOfRangeException(nameof(size));
            }

            try
            {
                // Since the socket is in blocking mode this will always complete
                // after ALL the requested number of bytes was transferred.
                _streamSocket.Send(buffer, offset, size, SocketFlags.None);
            }
            catch (SocketException socketException)
            {
                throw NetworkErrorHelper.MapSocketException(socketException);
            }
            catch (Exception exception) when(!(exception is OutOfMemoryException))
            {
                throw GetCustomNetworkException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
            }
        }
Exemplo n.º 9
0
        // Handle the end of an asynchronous write.
        // This method is called when an async write is completed. All we
        // do is call through to the core socket EndSend functionality.
        // Returns:  The number of bytes read. May throw an exception.
        public override void EndWrite(IAsyncResult asyncResult)
        {
            ThrowIfDisposed();

            // Validate input parameters.
            if (asyncResult == null)
            {
                throw new ArgumentNullException(nameof(asyncResult));
            }

            try
            {
                _streamSocket.EndSend(asyncResult);
            }
            catch (SocketException socketException)
            {
                throw NetworkErrorHelper.MapSocketException(socketException);
            }
            catch (Exception exception) when(!(exception is OutOfMemoryException))
            {
                throw GetCustomNetworkException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
            }
        }
Exemplo n.º 10
0
        public override void Write(ReadOnlySpan <byte> buffer)
        {
            if (GetType() != typeof(NetworkStream))
            {
                // NetworkStream is not sealed, and a derived type may have overridden Write(byte[], int, int) prior
                // to this Write(ReadOnlySpan<byte>) overload being introduced.  In that case, this Write(ReadOnlySpan<byte>)
                // overload should use the behavior of Write(byte[],int,int) overload.
                base.Write(buffer);
                return;
            }

            ThrowIfDisposed();
            if (!CanWrite)
            {
                throw new InvalidOperationException(SR.net_readonlystream);
            }

            _streamSocket.Send(buffer, SocketFlags.None, out SocketError errorCode);
            if (errorCode != SocketError.Success)
            {
                var exception = new SocketException((int)errorCode);
                throw NetworkErrorHelper.MapSocketException(exception);
            }
        }
Exemplo n.º 11
0
        protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(ValueTask.FromCanceled(cancellationToken));
            }

            try
            {
                if (method != ConnectionCloseMethod.GracefulShutdown)
                {
                    // Dispose must be called first in order to cause a connection reset,
                    // as NetworkStream.Dispose() will call Shutdown(Both).
                    _socket.Dispose();
                }

                // Since CreatePipe() calls CreateStream(), so _stream should be present even in the pipe case:
                _stream?.Dispose();
            }
            catch (SocketException socketException)
            {
                return(ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(NetworkErrorHelper.MapSocketException(socketException))));
            }
            catch (Exception ex)
            {
                return(ValueTask.FromException(ex));
            }

            return(default);