c - 为什么 getnameinfo() 检索重复的地址?
问题描述
我使用 BSD 套接字 API 中的 getnameinfo() 函数从主机获取地址,我想获取所有可用的地址:
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_ALL;
struct addrinfo *peer_address;
if (getaddrinfo(argv[1], NULL, &hints, &peer_address)) {
fprintf(stderr, "getaddrinfo() ERROR.\n");
return EXIT_FAILURE;
}
printf("Remote address(es):\n");
struct addrinfo *address = peer_address;
while((address = address->ai_next)) {
char address_buffer[100];
getnameinfo(address->ai_addr, address->ai_addrlen,
address_buffer, sizeof(address_buffer), 0, 0, NI_NUMERICHOST);
printf("\t> %s\n", address_buffer);
}
freeaddrinfo(peer_address);
并构建并运行此代码,我得到该输出:
$lookup google.com
Remote address(es):
> 172.217.203.100
> 172.217.203.100
> 172.217.203.102
> 172.217.203.102
> 172.217.203.102
.
.
.
> 2607:f8b0:400c:c07::8a
> 2607:f8b0:400c:c07::8a
> 2607:f8b0:400c:c07::8a
为什么每个 IP 地址都要打印两三遍?
解决方案
您会看到过度未指定的hints
变量的影响,这通常会将列表缩小到您所要求的范围内。
当您询问所有内容时,似乎对于每个 IP 地址,都有一个用于 tcp ( SOCK_STREAM
)、udp ( SOCK_DGRAM
) 以及 IP ( SOCK_RAW
) 的条目,但在仅查找 IP 地址的情况下——而不是服务——我看不出这有什么用。
解决此问题的简单方法是更新您的提示:
struct addrinfo hints;
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_ALL;
hints.ai_socktype = SOCK_RAW; // ADD ME
此外,您的循环确实跳过了第一个条目,因此替代可能是:
for (struct addrinfo *address = peer_address
; address != 0
; address = address->ai_next )
{
// do stuff
一个有用的参考:套接字编程中 addrinfo 名称的“提示”是什么意思
推荐阅读
- ignite - 如果它是我自己的类型,Apache Ignite 会根据远程服务代理方法返回一个代理吗?
- php - 是否可以通过循环来优化PDO中的大量BindValue?
- php - 有没有办法从 mssql 增量导出到 mysql?
- hash - Apple Homekit 设置哈希
- symfony - Symfony 5 - 错误:服务“uri_signer”依赖于不存在的参数“kernel.secret”。您的意思是:“kernel.charset”吗?
- python - 根据第一个条目从数组中删除重复项
- runtime - 适用于 Ubuntu 14.04 的 OpenCL 运行时库
- numpy - AttributeError:“numpy.ndarray”对象没有属性“strip”
- javascript - Countdown Javascript Timer 不适用于平板电脑和手机,但适用于台式机
- wpf - wpflocalizeextension 引用另一个项目中的 .resx 文件