Boost Asio的主机名解析如何在Linux上运行?是否可以使用NSS?

rof*_*fer 8 linux networking boost-asio

我正在尝试在没有网络连接的情况下使我的网络应用程序在本地工作(服务器和客户端都在同一台计算机上运行).这似乎偶尔"正常工作",但大多数时候我最终会:

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >'
       what(): Host not found (authoritative)
    Aborted
Run Code Online (Sandbox Code Playgroud)

我目前使用的代码是:

  tcp::resolver::query query(host, PORT);
  tcp::resolver::iterator endpointIterator = resolver.resolve(query);
  tcp::resolver::iterator end;

  boost::system::error_code error = boost::asio::error::host_not_found;
  while(error && endpointIterator != end)
  {
    mySocket.close();
    mySocket.connect(*endpointIterator++, error);
  }
  if(error)
    throw boost::system::system_error(error);
Run Code Online (Sandbox Code Playgroud)

我很确定我已经将问题缩小到ip :: basic_resolver :: resolve,但我无法弄清楚它是如何在Linux上实现的,或者我可能想要使用的其他内容. 似乎是同一个问题.似乎只是不执行任何查找,只使用127.0.0.1应该工作,但当我尝试用.替换查询行时

tcp::resolver::query query(host, PORT, boost::asio::ip::resolver_query_base::address_configured | boost::asio::ip::resolver_query_base::numeric_host
Run Code Online (Sandbox Code Playgroud)

它没有工作. 在我写这篇文章的过程中,我发现了我的错误,如果loopback设备是唯一一个带地址的设备,则address_configured标志(默认设置)会阻止resolve返回.我仍然发布这个问题,希望它可以帮助别人,但我已经解决了我的问题.

现在我用

tcp::resolver::query query(host, PORT, boost::asio::ip::resolver_query_base::numeric_service);
Run Code Online (Sandbox Code Playgroud)

虽然其他人可能不想要我正在使用的标志,如果他们想要查找服务名称(我只是使用端口号).

rof*_*fer 8

问题是查询的构造函数默认设置了address_configured标志,如果环回设备是唯一具有地址的设备,则不会返回地址.通过将设置标志设置为0或除address_configured以外的任何设置,问题得到修复.这是我现在成功使用的内容:

tcp::resolver::query query(host, PORT, boost::asio::ip::resolver_query_base::numeric_service);
Run Code Online (Sandbox Code Playgroud)

希望这有助于将来解决这个问题的任何人.


Tho*_*mas 5

查询的构造函数默认为具有标记"address_configured".

IP :: basic_resolver_query :: address_configured

如果为系统配置了非环回IPv4地址,则仅返回IPv4地址.如果为系统配置了非环回IPv6地址,则仅返回IPv6地址.

虽然将标志设置为其他内容将起作用,但它也会产生所述标志的副作用.为避免这种情况,请使用枚举的"默认值".

tcp::resolver::query query(host, PORT, boost::asio::ip::resolver_query_base::flags());
Run Code Online (Sandbox Code Playgroud)

过去可以只使用0,但库已经变得更加严格,以防止意外使用int作为服务名称.