来自 Boost.Asio 解析器的结果有所不同
results from Boost.Asio resolver differ
我有一个预制复制器每 5 秒在localhost
上调用一次boost::asio::ip::tcp::resolver::resolve()
。它计算返回的终结点数,并将该值与上一次迭代进行比较。
#include <boost/asio.hpp>
#include <iostream>
int main(int argc, char *argv[])
{
if ( argc < 3 ) {
std::cerr << argv[0] << " host port" << std::endl;
exit( EXIT_FAILURE );
}
const char* host = argv[1];
const char* service = argv[2];
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver( io_service );
size_t previous = 0;
while ( true ) {
boost::asio::ip::tcp::resolver::iterator i(
resolver.resolve(
boost::asio::ip::tcp::resolver::query( host, service )
)
);
size_t count( 0 );
while ( i != boost::asio::ip::tcp::resolver::iterator() ) {
std::cout << i->endpoint() << std::endl;
++i;
++count;
}
std::cout << "got " << count << " addresses" << std::endl;
if ( previous == 0 ) {
previous = count;
}
assert( count == previous );
sleep( 5 );
}
}
示例会话
~> time ./addrinfo_asio localhost 80
...
127.0.0.1:80
got 1 addresses
[::1]:80
127.0.0.1:80
got 2 addresses
addrinfo_asio: addrinfo_asio.cc:35: int main(int, char**): Assertion `count == previous' failed.
Aborted (core dumped)
real 216m20.515s
user 0m0.181s
sys 0m0.193s
~>
您可以看到它找到了一个端点 (127.0.0.1:80) 大约 3.5 小时,然后找到了两个端点 (127.0.0.1:80 和 [::1]:80)。我想知道
- 为什么端点计数从 1 变为 2?
- 什么原因可能导致它?
和 ipv6 地址是有意为之的,我不想将查询限制为仅 ipv4。我意识到这种行为可能不是特定于 asio,我还有一个直接调用getaddrinfo
的复制器表现出相同的行为。如果相关,我的平台是 ppc64 RHEL 6.2。我没有尝试在其他地方复制。
您只能将解析器限制为 IPv4:
ip::tcp::解析器::query(ip::tcp::v4(), host, service)
如果你看看Chris Kohlhoff(asio的作者)在boost con 2011上关于ipv6和asio的演讲,他做了以下技巧。
他重新排序端点列表,使ipv4端点在列表中排在第一位,并带有注释"现实检查:IPv6不太可能可用"。
他的示例代码适用于 boost 1.47 中发布的 asio 版本,但由于他习惯于随着C++的发展不断更改 asio 实现,因此在我正在使用的版本(asio 独立 1.18.0)中不再有效。
无论如何,以下代码适用于 asio 1.18.0,它包含在 boost 1.74 中
auto resolverResults(mResolver.resolve(hostName, serviceName));
std::transform(resolverResults.begin(), resolverResults.end(), std::back_inserter(endpoints), [](const asio::ip::basic_resolver_entry<asio::ip::tcp>& entry) { return entry.endpoint(); });
std::stable_partition(endpoints.begin(), endpoints.end(), [](const asio::ip::tcp::endpoint& endpoint) { return endpoint.protocol() == asio::ip::tcp::v4(); });
auto endpointsWithIP4First = asio::ip::tcp::resolver::results_type::create(endpoints.begin(), endpoints.end(), hostName, serviceName);
好吧,我不是提升专家,但快速浏览告诉我它似乎默认使用AI_ADDRCONFIG
(这很好,它几乎应该总是被使用)。使用该标志,仅当您配置了至少一个全局可路由 IPv6 地址时,它才会返回 IPv6 地址。也许您的 IPv6 连接并不总是可用?
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- valgrind-hellgrind与泄漏检查的结果不同
- 用C++20 fmt限制结果的总大小
- 如何返回一个类的两个对象相加的结果
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 序列化,没有库的整数,得到奇怪的结果
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 在更改for循环的第三部分后,未使用for循环结果
- 使用++运算符会导致意外的结果
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- C++Brute Force攻击函数不会返回结果
- GCC和Clang在与__builtin_constant_p相关的static_assert方面有所不同
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- Visual Studio 2015 EXP结果有所不同
- 当我有iostream和没有iostream时,结果会有所不同,但没有错误
- 来自 Boost.Asio 解析器的结果有所不同
- 如果在 SQUARE 宏中传递前缀变量,为什么结果会有所不同
- 相同的正则表达式搜索结果在C++和Java中有所不同