【问题标题】:SslStream.Read returns 0 on connected socketSslStream.Read 在连接的套接字上返回 0
【发布时间】:2016-02-15 13:14:41
【问题描述】:

有一个接口 IStream 来抽象 NetworkStream 和 SslStream。使用 NetworkStream 一切都很好,而 SslStream 在 Read 方法上有问题。这就是我建立 Ssl 流的方式:

class SecureStream : SslStream, IStream
{
    TcpClient _tcpClient;
    public SecureStream(TcpClient tcpClient) : base(tcpClient.GetStream()) {
        _tcpClient = tcpClient;
        var serverCertificate = new X509Certificate(@"C:\Cert.cer");
        AuthenticateAsServer(serverCertificate);
        ReadTimeout = -1;
        this.InnerStream.ReadTimeout = -1;
        _tcpClient.Client.ReceiveTimeout = -1;
    }
    ...
}

成功读取部分数据(http 标头)后,必须在 Read 方法上等待几秒钟,但 Read 方法立即返回 0。Ssl 连接保持活动状态,我可以在其他线程上写回响应。 Read 方法没有等待数据出现在流中的原因可能是什么?

【问题讨论】:

  • Read返回0时,表示对方已关闭连接。这里的所有都是它的。哦,上帝,请不要在构造函数中做这样的事情。找到一篇关于如何正确处理 SSL 的文章可能比尝试找到自己可以工作的东西更好。
  • 我同意,SSL 连接很棘手。我遇到了一个问题,该问题仅出现在服务器上的 Linux/OpenSSL 实现中。最好坚持现有的代码示例,而不是自己创建。
  • 另一端已连接,而 Read 返回 0 我可以成功写入同一个 Ssl 流。在构造函数中建立 SSL 连接如此邪恶的原因是什么?
  • 首先,确保引用您正在回复的人,例如@Jonas TCP 允许您从一侧关闭连接,而另一侧保持打开 - 您可以拥有一个客户端 -> 服务器,服务器 -> 客户端或客户端 服务器 TCP 连接。至于构造函数……哎哟。 AuthenticateAsServer 是一个虚方法,ReadTimeout 也是。从构造函数调用虚方法是一个很大的禁忌。除此之外,您还在构造函数中执行 I/O 工作。构造函数实际上不应该做太多事情 - 您可能希望为此使用静态方法。此外,构图值得研究。
  • 好的,我将重构并将接口更改为抽象类,并将流封装在实现中。但我的猜测是它不会解决这个问题,因为现在我有一个成功的 SSL 连接并且可以读写数据抛出它。还是我错了,有可能部分(仅一个方向)断开 SSL 流?

标签: c# .net sslstream


【解决方案1】:

事实证明,对于这种行为负责在构造函数内部建立 SSL 流(感谢 Luaan)。封装的 SslStream 版本按预期工作。

【讨论】:

    猜你喜欢
    • 2013-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多