2012-05-12 71 views
5

Tôi đang cố gắng phân giải tên máy chủ từ địa chỉ ip. Tôi đã thử sử dụng gethostbyaddr()getnameinfo() nhưng trong nhiều trường hợp tên máy chủ không được giải quyết chút nào. Có cách nào tốt hơn để chuyển một địa chỉ IP thành một tên máy chủ hợp lệ?Giải quyết ip thành tên máy chủ

char* ip = argv[1]; 
// using gethostbyaddr() 
hostent * phe = gethostbyaddr(ip, strlen(ip), AF_INET); 
if(phe) { 
    cout << phe->h_name << "\n"; 
} 

// using getnameinfo() 
char hostname[260]; 
char service[260]; 
sockaddr_in address; 
memset(&address, 0, sizeof(address)); 
address.sin_family = AF_INET; 
address.sin_addr.s_addr = inet_addr(ip); 
int response = getnameinfo((sockaddr*)&address, 
          sizeof(address), 
          hostname, 
          260, 
          service, 
          260, 
          0); 
if(response == 0) { 
    cout << hostname << "\n"; 
} 
+3

Không phải tất cả địa chỉ IP đều có tên máy chủ ngược. Điều gì khiến bạn nghĩ rằng các địa chỉ IP không trả về tên máy chủ lưu trữ phải có một địa chỉ? – Bruno

+1

@Bruno - Trong một số trường hợp khi tôi không nhận được tên máy chủ, tôi đã thử chạy 'nslookup

' từ thiết bị đầu cuối và lệnh này trả về tên máy chủ. Vì vậy, tôi đã nghĩ rằng có lẽ có một cách chính xác hơn để làm điều này. – Cyclonecode

+2

Tôi biết rằng đây không phải là câu trả lời NHƯNG bạn nên gắn bó với getaddrinfo và getnameinfo vì chúng hữu ích trong cả hai trường hợp cho địa chỉ mạng Ipv4 và Ipv6. – excanoe

Trả lời

5

Tôi đã cố gắng sử dụng gethostbyaddr()getnameinfo() [...]. Có cách nào tốt hơn để chuyển một địa chỉ IP thành một tên máy chủ hợp lệ?

Không, getnameinfo() là phương pháp được lựa chọn.


Bạn có thể kiểm tra kết quả của getnameinfo() chống EAI_AGAIN, và nếu thử lại bằng yêu cầu.


Đồng thời nhận được EAI_OVERFLOW không có nghĩa là bạn không có phản hồi. Nhưng dù sao như bạn cung cấp 259 ký tự đặt kết quả trong bạn sẽ hầu như không có khả năng nhận được một EAI_OVERFLOW ... ;-)


BTW: excanoe là đúng với his comment gắn bó với getaddrinfo()getnameinfo() ... - gethostbyaddr()gethostbyname() bằng cách nào đó không được chấp nhận. Việc xử lý (các) kết quả của chúng phức tạp và có xu hướng gây ra các lỗi lập trình.

4

Tôi đang sử dụng Windows để xin lỗi (bạn có thể bỏ qua phần WSADATA nếu bạn đang sử dụng * nix) về phiên bản này :)

#include <stdio.h> 
    #include <stdlib.h> 
    #include <stdint.h> 

    #include <winsock2.h> 

    int main(){ 
    struct addrinfo hints; 
    struct addrinfo *res=0; 
    int  status; 

    WSADATA wsadata; 
    int statuswsadata; 
    if((statuswsadata=WSAStartup(MAKEWORD(2,2),&wsadata))!=0){ 
     printf("WSAStartup failed: %d\n",statuswsadata); 
    } 

    hints.ai_family =AF_INET; 

    status=getaddrinfo("87.250.251.11",0,0,&res); 

    { 
     char host[512],port[128]; 

     status=getnameinfo(res->ai_addr,res->ai_addrlen,host,512,0,0,0); 

     printf("Host: %s",host); 

     freeaddrinfo(res); 
    } 
    } 

tôi có được điều này:

d:\temp\stack>ip 
Host: yandex.ru 

87.250.251.11 đó là địa chỉ mạng của máy chủ yandex.ru:

C:\Users\user>ping yandex.ru 

Pinging yandex.ru [87.250.251.11] with 32 bytes of data: 
Reply from 87.250.251.11: bytes=32 time=21ms TTL=56 
Reply from 87.250.251.11: bytes=32 time=21ms TTL=56 
Reply from 87.250.251.11: bytes=32 time=21ms TTL=56 

Ping statistics for 87.250.251.11: 
    Packets: Sent = 3, Received = 3, Lost = 0 (0% loss), 
Approximate round trip times in milli-seconds: 
    Minimum = 21ms, Maximum = 21ms, Average = 21ms 

Hy vọng thi s giúp.

Các vấn đề liên quan