我应该使用哪种类型的asio解析器对象?

Col*_*ews 5 boost-asio

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

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

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

  • 我可以互换使用吗?
  • 将名称解析为终结点之后,我计划使用TCP套接字进行连接。这是否意味着我必须使用ip :: tcp :: resolver?

如果实际上可以互换:

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

Tan*_*ury 6

使用与套接字具有相同协议的解析器。例如,tcp::socket::connect()期望为tcp::endpoint,而通过提供的端点类型udp::resolver::iteratorudp::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`
Run Code Online (Sandbox Code Playgroud)

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

在支持服务名称解析的系统上,使用描述性服务名称执行服务名称解析时,解析器的类型可能会影响结果。例如,在IANA服务名称和传输协议端口号注册表中

  • daytime服务使用的端口13上的UDP和TCP
  • 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);
}
Run Code Online (Sandbox Code Playgroud)