2011-01-31 32 views
6

Đây là những gì tôi đã làm cho đến nay. Nó biên dịch, nhưng nó phân biệt khi tôi cố gắng chạy nó.Làm cách nào để phân giải IP thành máy chủ bằng c-ares?

#include <iostream> 
#include <netdb.h> 
#include <arpa/inet.h> 
#include <ares.h> 

void dns_callback (void* arg, int status, int timeouts, struct hostent* host) 
    { 
    std::cout << host->h_name << "\n"; 
    } 

int main(int argc, char **argv) 
    { 
    struct in_addr ip; 
    char *arg; 
    inet_aton(argv[1], &ip); 
    ares_channel channel; 
    ares_gethostbyaddr(channel, &ip, 4, AF_INET, dns_callback, arg); 
    sleep(15); 
    return 0; 
    } 
+0

hệ điều hành gì? –

+0

Tôi đang sử dụng Linux. – greenman

+0

Tại sao bạn sử dụng 4 thay vì 'sizeof (in_addr)' cho chiều dài địa chỉ trong 'ares_gethostbyaddr()'? – chrisaycock

Trả lời

11

Bạn ít nhất phải initialize các ares_channel trước khi bạn sử dụng nó

if(ares_init(&channel) != ARES_SUCCESS) { 
    //handle error 
    } 

Bạn cũng cần một vòng lặp sự kiện để xử lý các sự kiện trên ares nộp mô tả và gọi ares_process để xử lý những sự kiện (phổ biến hơn, bạn muốn tích hợp điều này trong vòng lặp sự kiện của ứng dụng của bạn) Không có gì kỳ diệu với ares, nó không sử dụng các luồng để xử lý async vì vậy chỉ cần gọi giấc ngủ (15); không cho phép ares chạy trong "nền"

Gọi lại của bạn cũng nên kiểm tra biến số status, bạn không thể truy cập host->h_name nếu tra cứu không thành công.

Một ví dụ đầy đủ trở thành:

#include <time.h> 
#include <iostream> 
#include <netdb.h> 
#include <arpa/inet.h> 
#include <ares.h> 

void dns_callback (void* arg, int status, int timeouts, struct hostent* host) 
{ 
    if(status == ARES_SUCCESS) 
     std::cout << host->h_name << "\n"; 
    else 
     std::cout << "lookup failed: " << status << '\n'; 
} 
void main_loop(ares_channel &channel) 
{ 
    int nfds, count; 
    fd_set readers, writers; 
    timeval tv, *tvp; 
    while (1) { 
     FD_ZERO(&readers); 
     FD_ZERO(&writers); 
     nfds = ares_fds(channel, &readers, &writers); 
     if (nfds == 0) 
      break; 
     tvp = ares_timeout(channel, NULL, &tv); 
     count = select(nfds, &readers, &writers, NULL, tvp); 
     ares_process(channel, &readers, &writers); 
    } 

} 
int main(int argc, char **argv) 
{ 
    struct in_addr ip; 
    int res; 
    if(argc < 2) { 
     std::cout << "usage: " << argv[0] << " ip.address\n"; 
     return 1; 
    } 
    inet_aton(argv[1], &ip); 
    ares_channel channel; 
    if((res = ares_init(&channel)) != ARES_SUCCESS) { 
     std::cout << "ares feiled: " << res << '\n'; 
     return 1; 
    } 
    ares_gethostbyaddr(channel, &ip, sizeof ip, AF_INET, dns_callback, NULL); 
    main_loop(channel); 
    return 0; 
    } 
 
$ g++ -Wall test_ares.cpp -lcares 
$ ./a.out 8.8.8.8 
google-public-dns-a.google.com 
+0

Đó là sai lầm. Tôi đã không gọi ares_init. Chương trình hoạt động ngay bây giờ. – greenman

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