【问题标题】:Why does SSL Stream use a byte array of 2048?为什么 SSL Stream 使用 2048 的字节数组?
【发布时间】:2016-08-07 22:46:22
【问题描述】:

读取TCP SSL example from MSDN后,他们使用字节数组将数据读入流中。数组限制为 2048 是否有原因?如果 TCP 发送比 2048 更长的数组怎么办?此外,buffer.Length 属性如何继续读取流,因为它正在发生变化。这对我来说完全没有意义。为什么要读取缓冲区的长度,难道你不想读取进入流的增量字节的长度吗?

    static string ReadMessage(SslStream sslStream)
    {
        // Read the  message sent by the client.
        // The client signals the end of the message using the
        // "<EOF>" marker.
        byte [] buffer = new byte[2048];
        StringBuilder messageData = new StringBuilder();
        int bytes = -1;
        do
        {
            // Read the client's test message.
            bytes = sslStream.Read(buffer, 0, buffer.Length);

            // Use Decoder class to convert from bytes to UTF8
            // in case a character spans two buffers.
            Decoder decoder = Encoding.UTF8.GetDecoder();
            char[] chars = new char[decoder.GetCharCount(buffer,0,bytes)];
            decoder.GetChars(buffer, 0, bytes, chars,0);
            messageData.Append (chars);
            // Check for EOF or an empty message.
            if (messageData.ToString().IndexOf("<EOF>") != -1)
            {
                break;
            }
        } while (bytes !=0); 

        return messageData.ToString();
    }

【问题讨论】:

    标签: c# .net ssl tcp tcpclient


    【解决方案1】:

    当从任何类型的流(不仅仅是SslStream)读取时,仅仅因为您要求 X 字节,它们可以返回 1 到 X 字节之间的任何位置。这就是从Read 返回的bytes 的用途,看看你读了多少。

    如果你给Read 一个巨大的缓冲区,它只会填充前几个 1000 字节,给它一个更大的缓冲区是浪费空间。如果您需要的数据多于缓冲区的大小,则需要多次请求数据。

    处理网络流时要记住的重要一点是,发送方的一次写入并不意味着接收方的一次读取。写入可以组合在一起或在任意点分开,这就是为什么要有某种形式的Message Framing 才能知道您何时拥有“所有数据”。在您发布的示例中,他们使用标记 &lt;EOF&gt; 来表示“消息结束”。

    【讨论】:

    • 我是否应该假设 1 条消息的结尾和下一条消息的开头可能位于从 Read 方法返回的相同字节数组中?就像他们要发送多条消息一样,该流将读取第一个消息的尾端,而仅读取第二个...这意味着我必须预料到 在数组的中间?
    • 正确,来自 MSDN 的示例没有处理这种情况。如果一个多字节字符被分成两个单独的读取,它也会严重失败。在注释中他们说Use Decoder class to convert from bytes to UTF8 in case a character spans two buffers. 但是,如果确实发生了这种情况,他们所做的只是丢弃两个字节中的第一个字节,并且不做任何事情来处理下一次读取时的额外字节,从而导致此后的每次读取都可能被破坏,如果许多多- 连续发布的字节字符。
    • 通常您很少直接使用 NetworkStream 或 SslStream,通常会将其输入到 StreamReader 用于文本流或 BinaryReader 用于二进制流,它们处理“多条消息”的问题每次阅读”和“每次阅读拆分消息”,您只需从StreamReader.ReadLine() 读出您的String 或从BinaryReader.ReadInt32() 读出int
    • 您有什么好的参考资料可以解释如何将 StreamReader 与 SslStream 一起使用吗?我会使用 StreamReader 还是 BinaryReader?这很有趣。好的,我已将您的问题标记为答案,谢谢。
    • 不是真的,只要找到有关如何使用 StreamReader 的任何指南。这就是抽象的意义所在,它可以是 SslStream、NetworkStream 或 FileStream,它不会改变您使用 StreamReader 的方式。
    猜你喜欢
    • 2014-12-23
    • 1970-01-01
    • 2015-02-03
    • 2014-11-19
    • 2014-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    相关资源
    最近更新 更多