2012-03-11 94 views
1

這是一個簡單的程序,我寫它來找出域的所有A recordLinux網絡編程:getaddrinfo()得到錯誤的結果

我編制它,並沒有得到任何錯誤或警告。

然後我運行它,我只發現它給出錯誤的IP,如:

./a.out www.google.com

2.0.0.0

2.0.0.0

這是我的代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 
#include <netdb.h> 

int main(int argc, char *argv[]) 
{ 
    struct addrinfo addrC; 
    struct addrinfo *addrL; 
    struct addrinfo *temp; 

    memset(&addrC, 0, sizeof(addrC)); 
    addrC.ai_family = AF_INET; 
    addrC.ai_socktype = SOCK_STREAM; 
    addrC.ai_protocol = IPPROTO_TCP; 

    if (getaddrinfo(argv[1], "http", &addrC, &addrL) != 0) 
    { 
     perror("getaddrinfo!"); 
     exit(1); 
    } 

    for (temp = addrL; temp != NULL; temp = temp->ai_next) 
    { 
     char addrBuf[BUFSIZ]; 
     void *addrCount = &((struct sockaddr_in*)temp)->sin_addr; 
     inet_ntop(temp->ai_addr->sa_family, addrCount, addrBuf, sizeof(addrBuf)); 
     printf("%s\n", addrBuf); 
    } 
    for (temp = addrL; temp != NULL; temp = addrL) 
    { 
     addrL = temp->ai_next; 
     free(temp); 
    } 
    return 0; 
} 

爲什麼?以及如何糾正它?

+0

'struct addrinfo'不是'struct sockaddr_in',它們之間的投射可能會產生垃圾。您可以嘗試使用'temp-> ai_addr',而不是'sockadr_in'。 (爲什麼你命名結果'addrCount'超出了我的意思,它是一個地址,而不是任何數字)。 – 2012-03-11 07:53:41

回答

1

你必須在循環內部指針鑄造一個錯誤,它應該是:

void *addrCount = &((struct sockaddr_in*)temp->ai_addr)->sin_addr; 

否則,你正在閱讀的垃圾,並傳遞一個垃圾inet_ntop,所以你得到的垃圾,結果:)

1

其他答案是正確的,但我建議使用getnameinfo(使用NI_NUMERICHOST)而不是inet_ntop。那麼你首先不會有這個錯誤。

此外,你不應該循環並從getaddrinfo釋放結果。您可以撥打freeaddrinfo以釋放整個陣列。

+0

+1爲getnameinfo和其他一切。 – glglgl 2012-06-26 09:30:16