我写了下面的测试程序,我不能理解我得到的输出:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
int main(int argc, char** argv) {
struct addrinfo* results;
struct addrinfo hints;
char buf[INET6_ADDRSTRLEN+1];
if (argc != 2) {
exit(-1);
}
memset((char*) &hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
int ret = getaddrinfo(NULL, argv[1], &hints, &results);
if (ret) {
fprintf(stderr, "%s\n", gai_strerror(ret));
exit(-1);
}
for (struct addrinfo* ai = results; ai != NULL; ai = ai->ai_next) {
if (ai->ai_family == AF_INET) {
inet_ntop(AF_INET, ai, buf, INET_ADDRSTRLEN);
} else {
inet_ntop(AF_INET6, ai, buf, INET6_ADDRSTRLEN);
}
printf("%s\n", buf);
}
freeaddrinfo(results);
return 0;
}
在我的Fedora 23机器上,将打印以下内容:
1.0.0.0
100:0:a00:0:100:0:600:0
我的理解是,返回的IP地址应该是INADDR_ANY
和IN6ADDR_ANY_INIT
,这两个地址的值都应该是0
,即预期输出应该是0.0.0.0
和::0
。有人能给我解释一下这是怎么回事吗?
另一个相关的问题是,如果我的一个接口有一个host.domain.dom
解析到的IP,而我事先不确定该域是否有IPv6地址,我如何才能获得sockaddr
结构,以便我可以用来侦听该域的IPv4和IPv6地址,而不绑定到任何其他IP?即使在这种情况下忽略了AI_PASSIVE
标志,也向getaddrinfo
提供该主机名是否正确?
发布于 2016-09-17 06:38:37
您不应该将ai
本身作为参数提供给inet_ntop
;您应该提供指向实际网络地址的指针,而不是指向addrinfo
结构的指针。inet_ntop()
需要in_addr
和in6_addr
结构,因此根据ai->ai_family
将ai->ai_addr
类型转换为sockaddr_in*
或sockaddr_in6*
,然后分别传递其sin_addr
或sin6_addr
字段的地址。
if (ai->ai_family == AF_INET) {
inet_ntop(AF_INET, &(((sockaddr_in*)(ai->ai_addr))->sin_addr), buf, INET_ADDRSTRLEN);
} else {
inet_ntop(AF_INET6, &(((sockaddr_in6*)(ai->ai_addr))->sin6_addr), buf, INET6_ADDRSTRLEN);
}
关于你的第二个问题,我相信这将会回答它:
https://stackoverflow.com/questions/39537589
复制相似问题