2011-01-31 12 views
6

Questo è quello che ho fatto finora. Compila, ma segfaults quando provo a eseguirlo.Come posso risolvere un IP in host usando 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

Quale sistema operativo? –

+0

Sto usando linux. – greenman

+0

Perché stai usando 4 invece di 'sizeof (in_addr)' per la lunghezza dell'indirizzo in 'ares_gethostbyaddr()'? – chrisaycock

risposta

11

È atleast devono initialize l'ares_channel prima di usarlo

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

È inoltre necessario un ciclo di eventi per elaborare gli eventi sugli archivi di Ares descrittori e chiamano ares_process per gestire questi eventi (più comunemente, lo integreresti nel loop eventi della tua applicazione) Non c'è nulla di magico con ares, non usa i thread per eseguire l'elaborazione asincrona, semplicemente chiamando sleep (15); non lascia scappare ares nello "sfondo"

La richiamata deve anche controllare la variabile status, non è possibile accedere a host->h_name se la ricerca non è riuscita.

Un esempio completo diventa:

#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

Questo è stato l'errore. Non avevo chiamato ares_init. Il programma funziona ora. – greenman

Problemi correlati