C++ Boost Asio阻塞连接的超时时间

4

我有一个使用C++ Boost库的客户端,它会进行阻塞连接,并在收到响应后处理消息。但我遇到了一个奇怪的问题。

tcp::resolver::query query(tcp::v6(), this->host, port,tcp::resolver::query::v4_mapped);
iterator = resolver.resolve(query);
socket = new tcp::socket(io_service);
socket->connect(*iterator);

我尝试连接一台通过IPV6启用但ping6无法到达的机器。然而,在第二行解析查询时,我没有收到任何错误提示。因此,在出现错误之前尝试连接需要太长时间。我的问题如下:

1)是否可能在asio的阻塞连接中设置超时?我无法切换到异步操作模式。

2)为什么在解析无法到达的主机时不会出现错误?

任何建议都将非常有帮助。

2个回答

1

超时不是同步方法的正确位置,asio票务跟踪器中有一个漫长的讨论

我无法切换到异步操作模式。

考虑到超时要求,我认为这种情况高度不可能。请发布您代码的其余部分,并解释为什么您不能使用异步操作。


@Sam,感谢你的快速回复。实际上,超时不是必须的。主要问题是在查询无法连接的主机时,我会得到一个迭代器而没有错误。结果,该套接字会在大约5分钟(阻塞)后才发出错误信息:“尝试向无法访问的主机进行套接字操作”。 - confused
哦,我忘了补充一点,当我使用IPV6格式指定主机名时,我看到了这种行为。 - confused
通过将其与默认构造的迭代器进行比较,检查解析调用后的tcp::resolver::iterator的有效性。 - Sam Miller
1
@Sam..我尝试这样比较:-tcp::resolver::iterator defaultEnd; boost::system::error_code ec; iterator = resolver.resolve(query,ec); if (iterator == defaultEnd){ wcerr << L"V6 successful without errorcode, but possible unknown host" << endl; return; }因此,我将已解析的迭代器与默认构造的迭代器进行了比较。我认为这是正确的比较方式。但是,它并没有成功。我仍然得到一个“有效”的迭代器,在套接字中使用时失败。 - confused
如果您获得了有效的resolver::iterator,则建议使用带有计时器的async_connect,如果您不喜欢同步连接行为。 - Sam Miller
如何使用异步操作来完成它? - ingomueller.net

-1
当这个问题被提出时,我猜测ASIO没有任何关于如何完成OP所需的超时阻塞操作(例如阻塞套接字操作)的示例。现在有了示例,可以向您展示如何做到这一点。示例看起来很长,但这是因为它有非常详细的注释。它展示了如何在“一次性”模式下使用ioservice。
我认为这个示例是一个很好的解决方案。这里的其他解决方案会破坏可移植性,并且不利用ioservice。如果可移植性不重要,而ioservice似乎太过头疼,那么你就不应该使用ASIO。无论如何,你都将创建一个ioservice(几乎所有ASIO功能都依赖它,甚至同步套接字),所以要充分利用它。 ASIO阻塞调用超时示例 ASIO文档已经更新,请查看其中的新示例,以克服ASIO曾经存在的一些“陷阱”。

这个例子是关于异步操作的,而不是OP所问的内容。我相信这就是有人对这个答案进行负评的原因。 - lepe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接