使用libevent异步解析dns

本文介绍了如何使用libevent异步解析域名,特别提到了在Android平台上遇到的问题及解决方案,并提供了在Win7环境下配置DNS服务器的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.youkuaiyun.com/jiangjunshow

               

    libevent 自带 dns 解析库,支持同步、异步两种方式解析域名。因 libevent 本身是异步事件驱动型类库,我们在基于它做应用时,也多数是使用异步模型,因此这里介绍一下如何使用 libevent 异步解析域名。 libevent 官网有文章专门介绍 DNS 功能,请参考《Using DNS with Libevent》。

    我这里的例子和官网稍有不同,主要体现在对 DNS 服务器的配置上,区分了多平台。因为我发现在 Android (安卓)平台上, libevent 在获取 DNS 服务器时有问题,具体请参考另一篇博文《libevent 在 Android 上的一个改进》。

    我使用 libevent-2.1.3-alpha (请到官网下载)和 Qt 5.2 。关于 Qt 环境搭建,参考《Windows下Qt 5.2 for Android开发入门》。

    下面是所有代码:

struct event_base * g_evbase = 0;struct evdns_base * g_dnsbase = 0;static void _dns_callback(int errcode, struct evutil_addrinfo *addr, void *ptr){    if (errcode)    {        printf("%s -> %s\n", (char*)ptr, evutil_gai_strerror(errcode));    }    else    {        struct evutil_addrinfo *ai;        char ip[128];        printf("dns resolved,hostname - %s, ip :\n", (char*)ptr);        for (ai = addr; ai; ai = ai->ai_next)        {            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, ip, 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, ip, 128);            }            if(s)            {                printf("  %s\n", s);            }        }    }    if(addr)evutil_freeaddrinfo(addr);}struct evdns_base * setup_evdns_base(struct event_base *base){    if(g_dnsbase)    {        return g_dnsbase;    }    else    {        struct evdns_base * dnsbase = 0;#if defined(_WIN32)        dnsbase = evdns_base_new(base, 0);        evdns_base_nameserver_ip_add(dnsbase, "8.8.8.8");#elif defined(ANDROID)        dnsbase = evdns_base_new(base, 0);        {            int ret = 0;            int contains_default = 0;            char buf[PROP_VALUE_MAX];            ret = __system_property_get("net.dns1", buf);            if(ret >= 7)            {                if(!strncmp("8.8.8.8", buf, 7)) contains_default = 1;                evdns_base_nameserver_ip_add(dnsbase, buf);            }            ret = __system_property_get("net.dns2", buf);            if(ret >= 7)            {                if(!strncmp("8.8.8.8", buf, 7)) contains_default = 1;                evdns_base_nameserver_ip_add(dnsbase, buf);            }            if(!contains_default)            {                evdns_base_nameserver_ip_add(dnsbase, "8.8.8.8");            }        }#else        dnsbase = evdns_base_new(base, 1);#endif        printf(" dns server count : %d\n", evdns_base_count_nameservers(dnsbase));        g_dnsbase = dnsbase;        return dnsbase;    }}static int lookup_host(const char * host){    struct evutil_addrinfo hints;    struct evdns_getaddrinfo_request *req;    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;    req = evdns_getaddrinfo(g_dnsbase, host, NULL ,                &hints, _dns_callback, (void*)host);    if (req == NULL)    {        printf("    [request for %s returned immediately]\n", host);        return -1;    }    return 0;}int main(int argc, char **argv){#ifdef WIN32    WORD wVersionRequested;    WSADATA wsaData;    wVersionRequested = MAKEWORD(2, 2);    (void) WSAStartup(wVersionRequested, &wsaData);#endif    if(argc < 2)    {        printf("Usage: \n    dns_resolv hostname\n");        return 0;    }    g_evbase = event_base_new();    setup_evdns_base(g_evbase);    if(lookup_host(argv[1]) == 0)    {        event_base_loop(g_evbase, EVLOOP_NO_EXIT_ON_EMPTY);    }    event_base_free(g_evbase);    evdns_base_free(g_dnsbase, 1);#ifdef WIN32    (void) WSACleanup();#endif    return 0;}

    代码比较简单,从命令行获取待解析域名进行解析。通过 WIN32 ,ANDROID 这样一些宏来区分不同平台。

    需要说明一点,在我的 Win7 环境下,通过 evdns_base_new(base, 1) 这种方式无法读取到域名服务器,所以我配置了 google 的 8.8.8.8 来使用。

           

分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.youkuaiyun.com/jiangjunshow

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值