public static IDuplexPipe AsDuplexPipe(
        this WebSocket webSocket,
        WebSocketPipeReaderOptions?readerOptions = null,
        WebSocketPipeWriterOptions?writerOptions = null)
    {
        PipeReader reader = webSocket.AsPipeReader(readerOptions);
        PipeWriter writer = webSocket.AsPipeWriter(writerOptions);

        return(DefaultDuplexPipe.Create(reader, writer));
    }
    public static IDuplexPipe AsDuplexPipe(
        this Stream stream,
        StreamPipeReaderOptions?readerOptions = null,
        StreamPipeWriterOptions?writerOptions = null)
    {
        Requires.Argument(stream.CanRead, nameof(stream), @"Stream is not readable.");
        Requires.Argument(stream.CanWrite, nameof(stream), @"Stream is not writable.");

        PipeReader reader = PipeReader.Create(stream, readerOptions);
        PipeWriter writer = PipeWriter.Create(stream, writerOptions);

        return(DefaultDuplexPipe.Create(reader, writer));
    }
    public static IDuplexPipe AsShadowsocksPipe(
        this IDuplexPipe pipe,
        ShadowsocksServerInfo serverInfo,
        string targetAddress, ushort targetPort,
        PipeOptions?readerOptions = null,
        PipeOptions?writerOptions = null)
    {
        PipeReader reader = pipe.Input.AsShadowsocksPipeReader(serverInfo, readerOptions);
        PipeWriter writer = pipe.Output.AsShadowsocksPipeWriter(serverInfo, writerOptions);

        writer.WriteShadowsocksHeader(targetAddress, targetPort);

        return(DefaultDuplexPipe.Create(reader, writer));
    }