【问题标题】:Socket closing automatically套接字自动关闭
【发布时间】:2010-11-10 13:16:32
【问题描述】:

2h 后 Socket 应该自行关闭有什么原因吗?我每秒都从这个套接字接收数据,并每 30 秒写回一些微小的“保持活动”数据。

在发送之前,我使用以下方法检查套接字是否仍然连接:

public bool IsSocketReadyForWriting(Socket s)
{
   try
   {
      if (!s.Connected)
      {
          Log.Info("Socket.Connected was false");
          return false;
      }

      // following line will throw if socket disconnected
      bool poll = s.Poll(2000, SelectMode.SelectWrite);
      if (!poll)
      {
         try
         {
            // if poll is false, socket is closed
            Log.Info("poll is false");
            this.Close();
         }
         catch { }
         return false;
      }
      Log.Debug("still connected");
      return true;
   }
   catch (Exception ex)
   {
      Log.Error("Error while checking if socket connected", ex);
      return false;
   }
}

大约 2 小时一切正常,然后突然 Socket.Poll 返回 false,并且 Socket 被关闭。

是否有一个设置可以控制这一点,还是我做错了什么?

[编辑]

忘了说:我控制链接的服务器端和客户端。这些都是 C# 应用程序,其中一个创建侦听套接字,另一个打开连接并发送数据。他们在 2 小时内没有问题地进行通信(没有内存泄漏和其他东西),然后套接字关闭。

发生这种情况时,我可以轻松地重新连接套接字,但如果有人知道这可能是什么原因,我只是在徘徊。

【问题讨论】:

  • 测得的超时时间是否正好是 2 小时?或者只是围绕那个?另外,你控制中间的所有网络设备吗?

标签: c# .net sockets


【解决方案1】:

默认情况下,当套接字发送缓冲区中有至少一个字节的可用空间时,TCP 套接字是可写的。要扭转这种情况 - 当“输出队列”中有足够的未确认数据时,套接字是不可可写的。

也就是说,拔出wireshark 或Microsoft 为数据包嗅探提供的任何东西,看看网络上发生了什么。你的心跳块是否得到ACK-ed?接收器窗口是保持打开还是归零?还是您只是从某个中间开关获得明确的RSTFIN

缓解临时堵塞管道的一种方法是增加发送缓冲区大小,在 Windows 8192 iirc 上默认情况下它有点小。请参阅setsockopt(.NET 可能有一个版本)和SO_SNDBUF 选项。

【讨论】:

  • 谢谢,就是这样。我的虚拟客户端根本没有读取输入 TCP 流(几个 ping/状态字节),所以我的服务器输出缓冲区被填满了。
【解决方案2】:

可能是正在关闭连接的服务器?你能控制它吗?

【讨论】:

  • 哦,忘了说,我控制着服务器和客户端。它们都是 C# 应用程序。
  • AFAIK,2 小时是 SOL_KEEPALIVE 选项发送其证明后的超时时间(请参阅unixguide.net/network/socketfaq/4.7.shtml)。会不会是一侧启用了此选项,而另一侧未启用?
猜你喜欢
  • 2014-12-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-05
  • 1970-01-01
  • 2017-10-29
  • 2011-05-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多