解析查询与使用IP和端口创建端点之间的区别(在boost asio中)

Art*_*hur 10 c++ boost tcp boost-asio

我最近注意到我的应用程序存在问题,我认为这是因为我没有boost::asio正确使用并且不了解tcp解析器的功能.

基本上,我使用a boost::asio::ip::tcp::resolver来获取要连接的端点.

我最近发现的是它可以提供多个端点(特别是当我连接到localhost时).

目前我要求async_connect所有终点.我不是100%肯定,但我认为这很糟糕.我应该逐个向他们请求async_connect,等待回复并尝试下一个,当且仅当它失败时.

所以基本上知道如果我想async_connect在这些终点上使用我有两个选择:

  1. 重构我的代码,以便我的async_connect句柄失败正确并在失败时尝试连接到另一个可用的端点.我必须传递端点迭代器.

  2. 删除解析器并使用我自己构建的端点,如下所示: boost::asio::ip::tcp::endpoint("localhost", 20015)

我有种感觉,我应该使用第一个解决方案,并且解析器带来的东西比自构造的端点更多.

但解析器带来了什么,以及自构建端点如何自行解决?

Tan*_*ury 16

虽然Sam简洁地回答了大多数应用程序如何处理端点创建,但我想扩展它resolver.

所述resolver用于将地址的人类可读的文本表示形式转换成endpoint(多个)包含用于经由地址结构化二进制格式主机名解析或定义表示之间的转换.例如,resolver可能会解决人类可读"localhost"0x7F000001或转换"127.0.0.1"0x7F000001.Boost.Asio使用或模拟getaddrinfo()执行此分辨率.对于异步解析,将创建内部线程以执行操作.

另一方面,a basic_endpoint不能自行解决.虽然它不能用字符串和端口构造,但它可以用ip::address和端口构造.在ip::address可以从点分十进制形式(IPv4)的或十六进制表示法(IPv6)的字符串来构成:

namespace ip = boost::asio::ip;
ip::tcp::endpoint(ip::address::from_string("127.0.0.1"), 20015);
Run Code Online (Sandbox Code Playgroud)

提供主机ip::address::from_string()名将抛出异常:

namespace ip = boost::asio::ip;
ip::address::from_string("localhost"); // throws boost::system::system_error
Run Code Online (Sandbox Code Playgroud)

最后,使用:

  • resolver当您想要支持主机名解析或IP转换时.当IP可能更改但主机名保持不变,或者单个主机名可能解析为多个IP时,这尤其方便.
  • ip::address::from_string() 从IP创建地址.


Sam*_*ler 6

您是正确的,连接到解析操作返回的所有端点可能不是您的应用程序所期望的.选择#2不起作用,因为没有构造函数basic_endpoint(const char*, int).选择#1是如何构建几个asio示例,特别是异步tcp客户端演示超时.

重构代码以包含endpoint_iterator从解析器返回的代码不应该太困难,如果遇到问题,请按照上面的示例进行操作.请注意,它使用阻塞resolve()而不是async_resolve(),但概念是相同的.