c# - 用于读取和解码 SSL 消息的循环不起作用

标签 c# sockets ssl tcp pop3

我有这个循环来读取和解码 SSL 消息:

byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
// Works well to this moment
do
{
    bytes = sslStream.Read(buffer, 0, buffer.Length);
    Decoder decoder = Encoding.UTF8.GetDecoder();
    char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
    decoder.GetChars(buffer, 0, bytes, chars, 0);
    messageData.Append(chars);

    if (messageData.ToString().IndexOf("<EOF>") != -1)
        break;
} while (bytes != 0);
Console.Write(messageData.ToString());

当我调试它时,我在“locals”选项卡中看到 messageData 的值为 +OK Gpop ready for requests from xxx.xx.xx.xx p49mb48176339eey,但是循环不工作并且消息是' 打印到控制台。有人可以帮我吗?如果你想要完整的代码来测试,它在这里:github.com/WizzieP/MailerPrototype

最佳答案

您的代码的问题在于网络 TCP 流(以及位于其之上的 SSL 流)在与服务器的连接关闭之前不会从 Read() 返回 0。

因此,您需要使用其他方法来确定您是否已读取所有数据。

在您的情况下,由于您正在尝试读取 POP3 服务器问候语,因此您要做的是继续循环,直到您读取了 "\r\n" 序列(您可以也只需检查 '\n' 即可)。

当您开始执行 CAPA、UIDL、STAT、TOP 和 RETR 命令时,您将希望继续循环直到收到 "\r\n.\r\n"

如果您想了解有关如何执行此操作的一些高级技术,请随时在 https://github.com/jstedfast/MailKit/blob/master/MailKit/Net/Pop3/Pop3Stream.cs#L394 浏览我的代码。 (# 行可能会更改,但请查找 Read (byte[] buffer, int offset, int count, CancellationToken cancellationToken) 方法)。

此方法的作用是防止此流的使用者读取超出对 RETR 和 TOP 等命令的响应末尾的内容。在这样做的同时,它还取消字节填充正在从网络读取的数据(POP3 服务器将通过在以 开头的每一行前面添加一个>'.' 在 RETR 和 TOP 响应中),这样消费者就可以像从磁盘读取原始消息一样简单地读取流,而不必担心处理任何事情。

为此,您会注意到 Pop3Stream 缓冲数据。这就是 ReadAhead() 方法的职责。

这一切都是为了让我可以或多或少地直接从套接字解析消息,而不是在解析之前将所有数据读入 1 个大 StringBuffer:https://github.com/jstedfast/MailKit/blob/master/MailKit/Net/Pop3/Pop3Client.cs#L1275

除此之外,我的 MIME 解析器以增量方式解析消息(而不是将整个消息读入 1 个大 StringBuffer)这一事实使我的代码与所有其他 .NET POP3 库相比速度如此之快。

祝你好运!

关于c# - 用于读取和解码 SSL 消息的循环不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24697937/

相关文章:

python - 使用Python确定连接本地套接字的用户

ssl - 通过 SSL 检索的数据是否由客户端浏览器缓存?

c# - Unity C# 中的泛型

c# - Linq 中的 DateTime.Compare

C# 套接字与 C++ 套接字,哪个更好?

java - 服务器端无法接收数据(Java Socket编程)

c# - .NET:使用 C# 列出 HTTP 流量 URL

c# - 根据字符串位置对字符串数组进行排序 (C#)

php - 禁止通过 HTTPS 访问

ssl - 即使我有 key 和证书,nginx 也不支持加密协议(protocol)