asio :: ip :: tcp :: resolver :: async_resolve是否需要从外部取消?

时间:2020-10-20 12:46:44

标签: c++ c++11 network-programming boost-asio

我使用功能async_resolve()

using tcp = boost::asio::ip::tcp;

namespace asio = boost::asio;


template <class Request, class Response>
class HttpsClient : public std::enable_shared_from_this<HttpsClient<Request, Response>>
{
  mutable asio::io_context::strand  m_strand;
  tcp::resolver                     m_resolver;
  const std::string                 m_host;
  const std::string                 m_service;

  void doSend(Request request, Handler handler)
  {
    ...

    m_resolver.async_resolve(
      m_host, m_service,
      asio::bind_executor(
        m_strand, std::bind(&HttpsClient::onResolve, this->shared_from_this(), _1, _2)
      )
    );

    ... 
  }
  
  void onResolve(const boost::system::error_code& ec, tcp::resolver::results_type results);

例如,超时后我应该取消async_resolve()吗? 我的问题是-async_resolve()是否提供任何保证以智能时间限制返回。

1 个答案:

答案 0 :(得分:1)

我会有更高级别的超时,当它们无法及时完成时,它将取消任何DNS请求以及其他IO操作

毕竟,了解两者之间的差异只是一点点有趣,DNS解析通常是顺序IO链中的一个步骤,代表“查找,连接,握手,接收,回复”之类的事情。

当然,请确保记录超时的实际原因。这可以很简单:

 void on_timeout(error_code ec) {
     if (ec != asio::errors::operations_aborted)) {
          _resolver.cancel();
          _socket.cancel();
          // any other parts of the highlevel IO operation that might need cancelling
     }
 }

operations_aborted表示取消。因此,我们对其进行了检查,以避免在取消计时器本身时取消其他操作(例如,在析构函数期间自然发生的情况或设置新的到期时间)。

现在,您可以在完成处理程序中的各个步骤中检测到operations_aborted,并使用该记录进行适当记录(“ on_resolve:操作已中止”),以便您获取信息。如果希望的话,每当击打on_timeout时,您都可以添加一条更详细的消息,以便查看导致操作中止的其他逻辑流之间的差异。

我的问题是-async_resolve()是否提供任何保证以智能时间限制返回

我实际上不确定。以上就是原因。

假定所有DNS客户端不可避免地都有超时是非常合理的,因为该协议是UDP,这意味着数据包固有地易受影响。不能期望并处理数据包丢失是完全不负责任的(实际上,出于相同的原因,毫无疑问,将有“重试N次”的方法)。

我确实注意到一些其他应用程序在DNS没有响应时会卡住一定的固定时间,但是我不确定是什么导致它超时。我想它可能取决于平台。