我使用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
有用的引用:What's the "hints" mean for the addrinfo name in socket programming
关于c - 为什么getnameinfo()检索重复的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62252397/