2011-01-31 10 views
6

これまで私が行ってきたことです。それはコンパイルされますが、実行しようとするとsegfaultsします。c-aresを使用してIPをホストに解決するにはどうすればよいですか?

#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

どのオペレーティングシステム? –

+0

私はlinuxを使用しています。 – greenman

+0

'ares_gethostbyaddr()'のアドレス長に 'sizeof(in_addr)'の代わりに4を使用しているのはなぜですか? – chrisaycock

答えて

11

あなた少なくともあなたはまた、アールファイルディスクリプタ上のイベントを処理し、(より一般的に、これらのイベントを処理するためにares_processを呼び出すためにイベントループを必要とし、あなたがそれを使用する前に

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

をares_channelをinitializeする必要が aresには何も魔法がありません。非同期処理を行うためにスレッドを使用しないので、単にsleep(15)を呼び出します。

コールバックでもstatus変数を調べる必要があります。ルックアップが失敗した場合は、host->h_nameにアクセスすることはできません。

完全な例は次のようになります。

#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

それは間違いでした。私はares_initを呼ばなかった。プログラムは今働きます。 – greenman

関連する問題