2017-03-09 13 views
0

次のコードは、たとえばgoogle.comのIPアドレスの場合、常に0.0.0.0を返すため、わかりません。私はinet_ntoaと他の関数を使用する必要があります。誰でも私が鉛を知るのを助けることができましたか?特に、それは私が探しています何をしている同じ機能を使用して、なぜinet_ntoaは常に私のIPアドレスとして0.0.0.0を返すのですか?

#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/から運ばれたが、私のコードはほとんど同じことをやっています。

私が使用してコンパイル:getaddrinfo()機能は、クライアントが選択することが期待されているその中のアドレスのリンクリストを返す $ gcc hostname_to_ip.c && ./a.out www.google.com

+2

あなたが投稿したプログラムは、私にとってうまくいく:「www.google.comは74.125.192.147に解決されました」。システム/ネットワーク構成の詳細をご記入ください。 –

+0

私のインターネット接続はうまくいっていて、決して問題はありませんでした。私はdebianで走っています。私はsudoを使って試しましたが、何を提供したいですか? – ziKmouT

+0

eth0リンクカプセル化:イーサネットHWaddr 40:8d:5c:46:e9:87 inet addr:192.168.0.49 Bcast:192.168.0.255マスク:255.255.255.0 inet6 addr:fe80 :: 428d:5cff:fe46:e987/64範囲:リンク ブロードキャスト実行マルチキャストMTU:1500メトリック:1 RXパケット:24088エラー:0落ちた:0オーバーラン:0フレーム:0 TXパケット:18805エラー:0落ちた:0オーバーラン:0キャリア:0 0個のtxqueuelen:1000 RXバイト:14217983(13.5 MiB)TXバイト:2420577(2.3 MiB) – ziKmouT

答えて

1

。その関数に渡される "ヒント"オブジェクトによって、どのアドレスがリストに含まれているかに影響を与えることができます。取得したアドレスを処理するのにinet_ntoa()を使用する際には、IPv4と仮定しています。それは、理にかなって、その後、あなたは、IPv4でのみ興味を持っていることgetaddrinfo()を伝えるためには、アドレスになります。

hints.ai_family = AF_INET; 

私はあなたの元のコードを使用して結果を再現することができますが、1つの修正が私に合理的に見えるのIPv4アドレスを取得することを作ります代わりに。あなたはアドレスファミリーをチェックせずstruct sockaddr_in *にキャストgetaddrinfo()、によって提供されたアドレスのリストを歩くんが

は、あなたはそれの各アドレスは家族AF_INETであると仮定し。それは危険です。さらに、変換された各アドレス文字列を次のアドレス文字列に上書きするので、もしあなたが最も必要と思われるアドレスの優先順位をつけることがgetaddrinfo()であれば、それを破損に変えます。

IPv4アドレスのみを使用するように指定していない場合は、返されたアドレスファミリを使用するかどうかを決定する前に確認する必要があります。さらに、あなたは1つを返すような条項しか持っていないので、あなたが使えるものを見つけたらループから脱出するかもしれません。

関連する問題