10

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

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

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

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

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

  1. 重构我的代码,以便我async_connect正确处理失败,并在失败时尝试连接到其他可用端点。那么我将不得不通过端点迭代器。

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

我有一种感觉,我应该使用第一个解决方案,并且解析器带来的不仅仅是自构建的端点。

但是解析器带来了什么,自建端点如何自行解析呢?

4

2 回答 2

16

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

用于通过主机名解析或定义的表示之间的转换将地址的resolver人类可读文本表示转换为endpoint包含地址的结构化二进制格式的(s) 。例如,可以将人类可读的内容解析为或转换为. Boost.Asio 使用或模拟来执行此解决方案。对于异步解析,将创建一个内部线程来执行操作。resolver"localhost"0x7F000001"127.0.0.1"0x7F000001getaddrinfo()

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

namespace ip = boost::asio::ip;
ip::tcp::endpoint(ip::address::from_string("127.0.0.1"), 20015);

提供主机ip::address::from_string()名将引发异常:

namespace ip = boost::asio::ip;
ip::address::from_string("localhost"); // throws boost::system::system_error

最后,使用:

  • resolver当您想要支持主机名解析或 IP 转换时。当 IP 可能更改但主机名保持不变,或者单个主机名可能解析为多个 IP 时,这尤其方便。
  • ip::address::from_string()从 IP 创建地址。
于 2013-07-03T17:11:08.993 回答
6

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

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

于 2013-07-03T14:52:11.217 回答