【问题标题】:Detecting socket closing using boost::asio in Windows在 Windows 中使用 boost::asio 检测套接字关闭
【发布时间】:2012-10-25 20:09:04
【问题描述】:

所以我有一个服务方法,它使用io_service::poll() 来处理任何当前准备好的读/写事件:

void Foo::service()
{
  io.poll(); // boost::asio::io_service
  if (socket.is_open())
    if (socket.available())
      notifyReadyToRead();
    else
      notifyReadyToWrite();
}

但是,如果远程套接字关闭(优雅地或其他方式),我也想触发行为。我知道 Winsock 可以处理这个问题,因为它会在这种情况下引发网络事件。然而,据我所知,Boost Asio 套接字对此没有内置支持。

我已经尝试读取和写入一个零字节数据包到套接字以测试它是否有错误,但如果你在没有实际检查套接字的情况下传递它boost::asio::buffer(socket, 0),似乎实现只是成功地退出。

我还听说保留挂起的读取操作可能会起作用,但我不确定如何在仍然允许常规 boost::asio::read 和 'boost::asio::write` 操作正常工作的同时进行管理。

最后,在应用层协议中添加 ping 操作是不行的;此类旨在通用,即使不是我也无法更改远程端的协议。

虽然我更喜欢可移植的解决方案,但特定于 Windows 的解决方案就足够了,即使这意味着以这种方式获取本机句柄并枚举事件。 (这发生在我身上,但是WSAEnumNetworkEvents 清除了事件的内部记录,所以我怀疑如果 boost::asio 实现依赖于读取它会导致问题。)

【问题讨论】:

  • 任何操作系统都不支持通知远程套接字变得静默不可用/无法访问 - 协议不支持也不能支持它。

标签: c++ sockets boost-asio winsock disconnect


【解决方案1】:

在一般情况下,您必须实现一些应用程序级别的机制来检测各种断开连接。 关于这个话题,关于 boost/asio ML 的讨论很多,here is on of them

【讨论】:

    【解决方案2】:

    您可以启用套接字选项 TCP_KEEPALIVE,但仍需要挂起的读取操作才能接收读取失败的通知。

    【讨论】:

      猜你喜欢
      • 2016-10-27
      • 1970-01-01
      • 1970-01-01
      • 2019-10-21
      • 2016-05-25
      • 2019-10-12
      • 2012-01-16
      • 1970-01-01
      • 2017-10-07
      相关资源
      最近更新 更多