为什么 inet_ntoa 总是返回 0.0.0.0 作为 ip 地址?
Why is inet_ntoa always returning me 0.0.0.0 as the ip address?
我不明白,因为下面的代码总是返回 0.0.0.0 作为 google.com 的 IP 地址。我需要使用 inet_ntoa 而没有其他功能。谁能帮我算出 pb?
#include<stdio.h> //printf
#include<string.h> //memset
#include<stdlib.h> //for exit(0);
#include<sys/socket.h>
#include<errno.h> //For errno - the error number
#include<netdb.h> //hostent
#include<arpa/inet.h>
int hostname_to_ip(char * , char *);
int main(int argc , char *argv[])
{
if(argc <2)
{
printf("Please provide a hostname to resolve");
exit(1);
}
char *hostname = argv[1];
char ip[100];
hostname_to_ip(hostname , ip);
printf("%s resolved to %s" , hostname , ip);
printf("\n");
}
/*
Get ip from domain name
*/
int hostname_to_ip(char *hostname , char *ip)
{
int sockfd;
struct addrinfo hints, *servinfo, *p;
struct sockaddr_in *h;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_STREAM;
if ( (rv = getaddrinfo( hostname , "http" , &hints , &servinfo)) != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and connect to the first we can
for(p = servinfo; p != NULL; p = p->ai_next)
{
h = (struct sockaddr_in *) p->ai_addr;
strcpy(ip , inet_ntoa( h->sin_addr ) );
}
freeaddrinfo(servinfo); // all done with this structure
return 0;
}
它实际上是取自 http://www.binarytides.com/hostname-to-ip-address-c-sockets-linux/ 的代码,但我的代码几乎做同样的事情,尤其是它使用了我正在寻找的相同功能。
我编译:
$ gcc hostname_to_ip.c && ./a.out www.google.com
getaddrinfo()
函数 return 是一个地址链表,客户可以从中选择。您可以通过传递给该函数的 "hints" 对象来影响列表中包含哪些地址。在使用 inet_ntoa()
处理获得的地址时,您假设是 IPv4。那么,告诉 getaddrinfo()
您只对 IPv4 地址感兴趣是有道理的:
hints.ai_family = AF_INET;
我可以用您的原始代码重现您的结果,但进行一次修改后我会得到一个外观合理的 IPv4 地址。
虽然您确实遍历了 getaddrinfo()
提供的地址列表,但当您转换为 struct sockaddr_in *
而不检查地址族时,您 假设 每个地址它在家庭 AF_INET
中。那是不安全的。此外,您会用下一个覆盖每个转换后的地址字符串,因此如果 getaddrinfo()
很好地确定了您最可能需要的地址的优先级,那么您就会把它变成破损。
如果您没有指定只需要 IPv4 地址,那么至少您应该在决定是否使用之前检查每个 returned 地址的系列。而且,你只有return一个,所以当你找到一个你可以使用的时候,你还不如跳出循环。
我不明白,因为下面的代码总是返回 0.0.0.0 作为 google.com 的 IP 地址。我需要使用 inet_ntoa 而没有其他功能。谁能帮我算出 pb?
#include<stdio.h> //printf
#include<string.h> //memset
#include<stdlib.h> //for exit(0);
#include<sys/socket.h>
#include<errno.h> //For errno - the error number
#include<netdb.h> //hostent
#include<arpa/inet.h>
int hostname_to_ip(char * , char *);
int main(int argc , char *argv[])
{
if(argc <2)
{
printf("Please provide a hostname to resolve");
exit(1);
}
char *hostname = argv[1];
char ip[100];
hostname_to_ip(hostname , ip);
printf("%s resolved to %s" , hostname , ip);
printf("\n");
}
/*
Get ip from domain name
*/
int hostname_to_ip(char *hostname , char *ip)
{
int sockfd;
struct addrinfo hints, *servinfo, *p;
struct sockaddr_in *h;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_STREAM;
if ( (rv = getaddrinfo( hostname , "http" , &hints , &servinfo)) != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and connect to the first we can
for(p = servinfo; p != NULL; p = p->ai_next)
{
h = (struct sockaddr_in *) p->ai_addr;
strcpy(ip , inet_ntoa( h->sin_addr ) );
}
freeaddrinfo(servinfo); // all done with this structure
return 0;
}
它实际上是取自 http://www.binarytides.com/hostname-to-ip-address-c-sockets-linux/ 的代码,但我的代码几乎做同样的事情,尤其是它使用了我正在寻找的相同功能。
我编译:
$ gcc hostname_to_ip.c && ./a.out www.google.com
getaddrinfo()
函数 return 是一个地址链表,客户可以从中选择。您可以通过传递给该函数的 "hints" 对象来影响列表中包含哪些地址。在使用 inet_ntoa()
处理获得的地址时,您假设是 IPv4。那么,告诉 getaddrinfo()
您只对 IPv4 地址感兴趣是有道理的:
hints.ai_family = AF_INET;
我可以用您的原始代码重现您的结果,但进行一次修改后我会得到一个外观合理的 IPv4 地址。
虽然您确实遍历了 getaddrinfo()
提供的地址列表,但当您转换为 struct sockaddr_in *
而不检查地址族时,您 假设 每个地址它在家庭 AF_INET
中。那是不安全的。此外,您会用下一个覆盖每个转换后的地址字符串,因此如果 getaddrinfo()
很好地确定了您最可能需要的地址的优先级,那么您就会把它变成破损。
如果您没有指定只需要 IPv4 地址,那么至少您应该在决定是否使用之前检查每个 returned 地址的系列。而且,你只有return一个,所以当你找到一个你可以使用的时候,你还不如跳出循环。