【发布时间】: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 流?