我不明白,因为以下代码总是以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
答案 0 :(得分:1)
getaddrinfo()
函数返回一个链接的地址列表,其中客户端应该选择。您可以通过&#34;提示&#34;来影响列表中包含的地址。传递给该函数的对象。在使用inet_ntoa()
处理获得的地址时,您假设使用IPv4。那么,告诉getaddrinfo()
您只对IPv4地址感兴趣是有道理的:
hints.ai_family = AF_INET;
我可以使用您的原始代码重现您的结果,但进行一次修改会让我找到一个合理的IPv4地址。
虽然你走了getaddrinfo()
提供的地址列表,当你在不检查地址系列的情况下转换为struct sockaddr_in *
时,你假设其中的每个地址都在家庭中AF_INET
。那是不安全的。此外,您使用下一个转换地址字符串覆盖每个转换后的地址字符串,因此,如果getaddrinfo()
能够优先处理您最有可能需要的地址,那么您可以将其转换为破损地址。
如果您没有指定只需要IPv4地址,那么在决定是否使用IPv4地址之前,至少应该检查每个返回的地址的系列。此外,您只需要返回一个,所以一旦找到可以使用的循环,您也可以摆脱循环。