This is what I've done so far. It compiles, but it segfaults when I try to run it.
#include <iostream>
#include <netdb.h>
#include <arpa/i开发者_开发百科net.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;
}
You atleast have to initialize the ares_channel before you use it
if(ares_init(&channel) != ARES_SUCCESS) {
//handle error
}
You also need an event loop to process events on the ares file descriptors and call ares_process to handle those events (more commonly, you'd integrate this in the event loop of your application) There's nothing magic with ares, it doesn't use threads to do the async processing so simply calling sleep(15); doesn't let ares run in the "background"
Your callback should also inspect the status
variable, you can't access host->h_name
if the lookup failed.
A full example becomes:
#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
精彩评论