首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自愈型SslStream

自愈型SslStream
EN

Stack Overflow用户
提问于 2014-08-29 18:52:31
回答 2查看 638关注 0票数 0

我正在编写一个服务,它需要维护到远程服务器的长期运行的SSL连接。我需要这台服务器能够自我修复,也就是说,如果它因任何原因断开连接,那么下一次写到它时,它将重新连接。我试过这个:

代码语言:javascript
复制
bool isConnected = client.Connected && client.Client.Poll(0, SelectMode.SelectWrite) && stream.CanWrite;

if (!isConnected )
{
    this.connected = false;
    GetConnection();
}

stream.Write(bytes, 0, bytes.Length);
stream.Flush();

但我发现它不像我所期望的那样。如果我通过禁用wifi来模拟网络中断,我仍然能够用stream.Write()写入流大约20秒。然后,下次我尝试写它时,client.Connected、client.Client.Poll()或stream.CanWrite()都不会返回false,但是当我写到流时,我会得到一个套接字异常。最后,如果我尝试重新创建连接,就会得到这个异常:一个现有的连接被远程主机强制关闭。

我希望任何帮助创建一个长期运行的SslStream,可以抵御网络故障。谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-30 05:36:40

SSL的底层协议是TCP。TCP通常只在应用程序希望发送数据时发送数据,或者需要通过发送ACK来回复从另一方接收的数据。这意味着,在尝试发送任何数据之前,将不会注意到断开的连接(如丢失的链接)。但你不会立即注意到,因为:

  • 对套接字的写入只会将数据传递到OS内核,如果此传递成功,则返回成功。
  • 然后,内核将尝试将数据传递给对等程序,并等待来自客户端的ACK。
  • 如果它没有得到任何ACK,它将再次重试以传递数据,并且只有在一些不成功的重试之后,内核才会声明连接中断。
  • 只有在连接被内核标记为断开后,下一个写或读才会将错误从内核返回到用户空间,就像在编写时返回EPIPE一样。

这意味着,如果您想要预先知道连接是否仍然有效,您必须确保在连接上进行定期的数据交换。在TCP级别上,您可以设置TCP_KEEPALIVE,但这可能会在交换数据包之间使用几个小时的间隔。在SSL层,您可能尝试使用臭名昭著的心跳扩展,但大多数对等方都不会理解它。最后一种选择是在自己的应用程序中实现某种心跳。

至于自愈:当重新连接时,您将得到一个新的TCP连接,并且您还需要进行一个完整的SSL握手,因为最后一个SSL连接没有完全关闭,因此无法恢复。服务器不知道这个新连接只是旧连接的延续,因此您必须在客户端和服务器上实现跨应用程序层内多个TCP连接的某种元连接。在这个元连接中,您需要有自己的数据跟踪来检测哪些数据真正从对等端被接受,哪些数据只被发送,但由于连接中断而从未被显式接受。听起来像是TCP上的TCP。

票数 0
EN

Stack Overflow用户

发布于 2014-08-29 21:21:36

从10.000英尺的角度看:

关闭wifi后仍然可以写入流的原因是,有一个网络缓冲区保存数据以进行传输。reach的成功意味着网络接口(TCP/IP堆栈)已接受该数据并已被缓冲以进行传输,而不是数据已到达其目标。

TCP/IP堆栈需要时间才能注意到完全的媒体断开(连接丢失/重置),因为即使没有物理链接,TCP/IP也会将其视为网络中的一个临时问题,并将持续重试一段时间(网络可能在某个时候丢弃数据包,堆栈将继续重试)。

如果您以相反的方式考虑这一点,您不会希望所有的程序都失败,如果有网络问题(这种情况在互联网上经常发生),因此TCP/IP会花时间通知应用程序层连接已失效(经过多次重试并等待了合理的时间)。

当SslStream失败并继续发送数据时,您可以始终重新连接到服务器,尽管您会发现这并不容易,因为有几种情况下,您发送的数据和服务器没有接收到数据,而服务器完全没有从服务器接收任何ACK .因此,根据你的需要,光靠自我治疗是不够的。

自愈实现简单,数据一致性和可靠性更难,通常要求服务器准备支持某种可靠的消息传递机制,以确保所有数据都已发送和接收。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25574515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档