使用boost :: asio在Windows中检测插座关闭

Detecting socket closing using boost::asio in Windows

本文关键字:检测 插座 Windows boost asio 使用      更新时间:2023-10-16

所以我有一种使用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操作添加到App级协议中是无关的。此类旨在一般使用,即使不是,我也无法更改远程端的协议。

虽然我更喜欢一种便携式解决方案,但特定于Windows的解决方案就足够了,即使这意味着以这种方式抓住本机手柄和枚举事件。(这是我发生的,但是WSAEnumNetworkEvents清除了事件的内部记录,因此我怀疑如果Boost :: Asio实施取决于阅读它会导致问题。)

在一般情况下,您必须实现一些应用程序级别的机制来检测各种断开连接。关于Boost/ASIO ML在此主题上进行了许多讨论,这是其中的。

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