为了账号安全,请及时绑定邮箱和手机立即绑定

带有 System.IO.Pipelines 的 TLS/SSL

带有 System.IO.Pipelines 的 TLS/SSL

C#
MM们 2022-06-12 15:24:43
我注意到新的 System.IO.Pipelines 并试图将现有的、基于流的代码移植到它上面。流的问题很好理解,但同时它具有相关类的丰富回声系统。从这里提供的示例中,有一个小型 tcp echo 服务器。 https://blogs.msdn.microsoft.com/dotnet/2018/07/09/system-io-pipelines-high-performance-io-in-net/此处附有一段代码:    private static async Task ProcessLinesAsync(Socket socket)    {        Console.WriteLine($"[{socket.RemoteEndPoint}]: connected");        var pipe = new Pipe();        Task writing = FillPipeAsync(socket, pipe.Writer);        Task reading = ReadPipeAsync(socket, pipe.Reader);        await Task.WhenAll(reading, writing);        Console.WriteLine($"[{socket.RemoteEndPoint}]: disconnected");    }    private static async Task FillPipeAsync(Socket socket, PipeWriter writer)    {        const int minimumBufferSize = 512;        while (true)        {            try            {                // Request a minimum of 512 bytes from the PipeWriter                Memory<byte> memory = writer.GetMemory(minimumBufferSize);                int bytesRead = await socket.ReceiveAsync(memory, SocketFlags.None);                if (bytesRead == 0)                {                    break;                }                // Tell the PipeWriter how much was read                writer.Advance(bytesRead);            }            catch            {                break;            }            // Make the data available to the PipeReader            FlushResult result = await writer.FlushAsync();            if (result.IsCompleted)            {                break;            }        }        // Signal to the reader that we're done writing        writer.Complete();    }使用流时,您只需将 SSL/TLS 包装在 SslStream 中即可轻松将其添加到代码中。Pipelines 打算如何解决这个问题?
查看完整描述

1 回答

?
慕婉清6462132

TA贡献1804条经验 获得超2个赞

命名管道是一种网络协议,就像 HTTP、FTP 和 SMTP 一样。让我们看一下 .net 框架的一些简单示例:

  • HTTP 连接自动利用 SSL,具体取决于基本 URI。如果 URI 带有“HTTPS:”,则使用 SSL。

  • FTP 连接手动利用 SSL,方法是在调用 GetResponse() 之前将 EnableSsl 属性设置为 true。

  • SMTP 以与 FTP 相同的方式利用 SSL。

但是如果我们使用不同的网络协议,比如管道呢?我们马上就知道没有类似于“HTTPS”前缀的东西。此外,我们可以阅读 System.IO.Piplines 的文档,发现没有“EnableSsl”方法。但是,在 .NET Framework 和 .NET Core 中,都可以使用 SslStream 类。此类允许您从几乎任何可用的 Stream 中构建 SslStream。

System.IO.Pipes 命名空间也可用于 .NET Framework 和 .NET Core。Pipes 命名空间中可用的类非常有用。

  • 匿名管道客户端流

  • 匿名管道服务器流

  • NamedPipeClientStream

  • 命名管道服务器流

  • 管道流

所有这些类都返回某种从 Stream 继承的对象,因此可以在 SslStream 的构造函数中使用。

这与 System.IO.Piplines 命名空间有何关系?嗯......它没有。System.IO.Pipelines 命名空间中定义的类、结构或接口都不是从 Stream 继承的。所以我们不能直接使用 SslStream 类。

相反,我们可以访问 PipeReaders 和 PipeWriters。有时我们只有其中一个可用,但让我们考虑一个双向管道,以便我们可以同时访问两者。

System.IO.Piplines 命名空间提供了一个 IDuplexPipe 接口。如果我们想将 PipeReader 和 PipeWriters 包装在 SSL 流中,我们需要定义一个实现 IDuplexPipe 的新类型。

在这种新类型中:

  • 我们将定义一个 SslStream。

  • 我们将使用通用管道作为输入和输出缓冲区。

  • PipeReader 将使用输入缓冲区的读取器。我们将使用这个输入缓冲区从 SSL 流中获取数据。

  • PipeWriter 将使用输出缓冲区的写入器。我们将使用此输出缓冲区将数据发送到 SSL 流。

下面是一个伪代码示例:

SslStreamDuplexPipe : IDuplexPipe

    SslStream sslStream;

    Pipe inputBuffer;

    Pipe outputBuffer;


    public PipeReader Input = inputBuffer.Reader;

    public PipeWriter Output = outputBuffer.Writer;


    ReadDataFromSslStream()

    {

        int bytes = sslStream.Read(new byte[2048], 0, 2048);

        inputBuffer.Writer.Advance(bytes)

        inputBuffer.Writer.Flush();

    }


    //and the reverse to write to the SslStream 

 }

如您所见,我们仍在使用 System.Net.Security 命名空间中的 SslStream 类,只是多走了几步。

这是否意味着您基本上仍在使用流?是的!但是,一旦你完全实现了你的 SslStreamDuplexPipe 类,你就可以只使用管道了。无需将 SslStream 包裹在所有内容中。


查看完整回答
反对 回复 2022-06-12
  • 1 回答
  • 0 关注
  • 150 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信