繁体   English   中英

C#SocketAsyncEventArgs和网络故障

[英]C# SocketAsyncEventArgs and network glitches

我已经以规范的方式使用SAEA实现了异步套接字:

  1. 拥有准备运行的SAEA池,保留引用,以便GC不必移动内存
  2. 操作完成后,请更换SAEA。

我发现了与网络中断有关的问题。 具体来说, 当发生中断时 ,sendAsync完成事件不会触发 ,因此不会重新填充我的池。 最终最终导致程序崩溃,因为无论池的大小如何,它都将耗尽SAEA。

您如何避免这种情况? 您不能简单地保留对旧SAEA的引用,因为这将为您提供一个例外,表明它已经在等待操作。

我正在寻找一种方法来优雅地替换SAEA。 数据不被传输不是问题。 一种可行的方法是一旦有一定数量的对象正在等待,就在套接字上运行关机。 有人有经验吗?

实际上,在基本无限的网络延迟情况下(就像在切断电缆的情况下),没有完成没有发布。

解决此类问题的唯一方法是实施某些版本的心跳方案。 套接字上存在SO_KEEPALIVE选项,但是默认行为通常不是您想要的。 从MSDN:

对于TCP,默认的保持活动超时时间为2小时,保持活动时间间隔为1秒。

我建议您实施自己的心跳方案,如果在合理的时间内未收到响应心跳,则认为连接“死”。 例如,您可以:

  1. 定期发送“心跳”(或没有其他消息发送时)
  2. 记下接收到心跳(或任何)消息的时间,并设置超时,以便如果触发了超时,则表示您接收数据的时间太长,因此应关闭连接并重新启动

提出的解决方案确实有效。 只需在每次发送之前检查是否超出了某个限制,然后关闭并关闭套接字即可。 这样可以防止对象泄漏,并在以后允许正常重新连接。

我通过拔下电缆并反复重新连接进行了测试。 在旧情况下,池将为空。 现在,它可以在网络中断后幸存下来。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM