利用libevent非阻塞方式进行dns解析
代码如下:
#include <stdio.h>
#include <event2/util.h>
#include <event2/event.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
int n_pending_requests = 0;
struct event_base *base = NULL;
struct user_data
{
char *name;
int idx;
};
void call_back(int errcode, struct evutil_addrinfo *addr, void *ptr)
{
struct user_data *data = ptr;
const char *name = data->name;
if(errcode)
{
printf("%d.%s->%s\n", data->idx, name, evutil_gai_strerror(errcode));
}
else
{
struct evutil_addrinfo *ai;
printf("%d.%s", data->idx, name);
if(addr->ai_canonname)
printf("[%s]", addr->ai_canonname);
puts("");
for(ai = addr; ai; ai=ai->ai_next)
{
char buf[128];
const char *s = NULL;
if(ai->ai_family == AF_INET)
{
struct sockaddr_in *sin = (struct sockaddr_in*)ai->ai_addr;
s = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, 128);
}
else if(ai->ai_family == AF_INET6)
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)ai->ai_addr;
s = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, 128);
}
if(s)
{
printf(" ---->%s\n", s);
}
}
evutil_freeaddrinfo(addr);
}
free(data->name);
free(data);
if(--n_pending_requests == 0)
event_base_loopexit(base, NULL);
}
int main(int argc, char *argv[])
{
int i;
struct evdns_base *dnsbase;
if(argc ==1)
{
puts("NO address given.");
return 0;
}
base = event_base_new();
if(!base)
return 1;
dnsbase = evdns_base_new(base, 1);
if(!dnsbase)
return 2;
for(i=1;i<argc;++i)
{
struct evutil_addrinfo hints;
struct evdns_getaddrinfo_request *req;
struct user_data *user_data;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_flags = EVUTIL_AI_CANONNAME;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if(!(user_data = malloc(sizeof user_data)))
{
perror("malloc");
exit(1);
}
if(!(user_data->name = strdup(argv[i])))
{
perror("strdup");
exit(1);
}
user_data->idx = i;
++n_pending_requests;
req = evdns_getaddrinfo(dnsbase, argv[i], NULL, &hints, call_back, user_data);
if(req == NULL)
printf("[request for %s returned immediately]\n", argv[i]);
}
if(n_pending_requests)
{
event_base_dispatch(base);
}
evdns_base_free(dnsbase, 0);
event_base_free(base);
return 0;
}
gcc -g -o libevent_dns libevent_dns.c -levent
# ./libevent_dns www.baidu.com blog.youkuaiyun.com
1.www.baidu.com[www.a.shifen.COm]
---->220.181.111.188
---->220.181.112.244
2.blog.youkuaiyun.com
---->114.112.73.198