2

所以我有一个服务方法用于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 实现依赖于读取它会导致问题。)

4

2 回答 2

0

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

于 2012-10-29T00:45:18.063 回答
0

在一般情况下,您必须实现一些应用程序级别的机制来检测各种断开连接。关于这个主题有很多关于 boost/asio ML 的讨论,这里是其中的一个

于 2012-10-27T12:39:00.227 回答