【问题标题】:What type of asio resolver object should I use?我应该使用什么类型的 asio 解析器对象?
【发布时间】:2016-11-22 20:29:21
【问题描述】:

对于我正在处理的副项目应该使用哪种类型的解析器,我有点困惑。我在 asio 文档中找不到答案。

我知道 DNS 可以与 UDP 或 TCP 一起使用,并且通常通过 TCP 发送较大的响应。

asio 同时提供 ip::tcp::resolver 和 ip::udp::resolver。

  • 我可以互换使用它们吗?
  • 将名称解析为端点后,我计划连接 一个 TCP 套接字。这是否意味着我必须使用 ip::tcp::resolver?

如果实际上可以互换:

  • 使用 UDP 解析器有性能优势吗?
  • 使用 TCP 解析器还有其他好处吗?
  • 如果我使用 UDP 解析器,是否需要处理响应太大而无法进行 UDP 查找并使用 TCP 重试? (我希望连接到将解析为每个主机多个 IP 地址的 CDN)

【问题讨论】:

    标签: boost-asio


    【解决方案1】:

    使用与套接字具有相同协议的解析器。例如,tcp::socket::connect() 需要 tcp::endpoint,而通过 udp::resolver::iterator 提供的端点类型是 udp::endpoint。尝试直接使用不同协议的查询结果会导致编译错误:

    boost::asio::io_service io_service;  
    boost::asio::ip::tcp::socket socket(io_service);
    boost::asio::ip::udp::resolver::iterator iterator = ...;
    socket.connect(iterator->endpoint());
    // ~~~^~~~~~~ no matching function call to `tcp::socket::connect(udp::endpoint)`
    //            no known conversion from `udp::endpoint` to `tcp::endpoint`
    

    tcp::resolverudp::resolver 都没有规定名称解析将使用的传输层协议。 DNS 客户端将在必要时或已明确配置为使用 TCP 时使用 TCP。

    在支持服务名称解析的系统上,当使用描述性服务名称执行服务名称解析时,解析器的类型会影响结果。比如在IANA Service Name and Transport Protocol Port Number Registry

    • daytime 服务在 UDP 和 TCP 上使用端口 13
    • shell 服务仅在 TCP 上使用端口 514
    • syslog 服务仅在 UDP 上使用端口 514

    因此,可以使用tcp::resolver 来解析daytimeshell 服务,但不能使用syslog。另一方面,udp::resolver 可以解析daytimesyslog,但不能解析shell。以下示例演示了这种区别:

    #include <boost/asio.hpp>
    
    int main()
    {
      boost::asio::io_service io_service;
    
      using tcp = boost::asio::ip::tcp;
      using udp = boost::asio::ip::udp;
    
      boost::system::error_code error;
      tcp::resolver tcp_resolver(io_service);
      udp::resolver udp_resolver(io_service);
    
      // daytime is 13/tcp and 13/udp
      tcp_resolver.resolve(tcp::resolver::query("daytime"), error);
      assert(!error);
      udp_resolver.resolve(udp::resolver::query("daytime"), error);
      assert(!error);
    
      // shell is 514/tcp
      tcp_resolver.resolve(tcp::resolver::query("shell"), error);
      assert(!error);
      udp_resolver.resolve(udp::resolver::query("shell"), error);
      assert(error);
    
      // syslog is 514/udp
      tcp_resolver.resolve(tcp::resolver::query("syslog"), error);
      assert(error);
      udp_resolver.resolve(udp::resolver::query("syslog"), error);
      assert(!error);
    
      tcp_resolver.resolve(tcp::resolver::query("514"), error);
      assert(!error);
      udp_resolver.resolve(udp::resolver::query("514"), error);
      assert(!error);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-18
      • 2020-12-21
      • 2015-03-09
      • 1970-01-01
      • 2017-04-14
      • 1970-01-01
      • 2021-08-22
      • 2022-01-18
      相关资源
      最近更新 更多