【发布时间】: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