土法炼钢兴趣小组的算法知识备份

异步 DNS 解析 (evdns)

目录

在编写网络客户端时,域名解析(DNS)往往是一个被忽视的性能杀手。标准的 getaddrinfogethostbyname同步阻塞的。如果 DNS 服务器响应慢,你的 Event Loop 就会卡住,导致所有连接超时。

Libevent 提供了 evdns 模块,实现了完全异步的 DNS 解析器。

1. 为什么需要 evdns?

2. 基本用法

2.1. 初始化

#include <event2/dns.h>

struct evdns_base *dns_base = evdns_base_new(base, 1);
if (!dns_base) {
    // handle error
}

第二个参数 1 表示初始化默认的 nameservers(在 Linux 上读取 /etc/resolv.conf,在 Windows 上读取注册表)。

2.2. 发起查询

void dns_cb(int result, char type, int count, int ttl, void *addresses, void *arg) {
    if (result != DNS_ERR_NONE) {
        printf("DNS resolve failed: %s\n", evdns_err_to_string(result));
        return;
    }

    if (type == DNS_IPv4_A) {
        struct in_addr *addrs = (struct in_addr *)addresses;
        for (int i = 0; i < count; ++i) {
            char buf[64];
            inet_ntop(AF_INET, &addrs[i], buf, sizeof(buf));
            printf("IP: %s\n", buf);
        }
    }
}

// 查询 A 记录 (IPv4)
evdns_base_resolve_ipv4(dns_base, "www.google.com", 0, dns_cb, NULL);

3. 高级特性

3.1. 自定义 Nameserver

你可以不使用系统的 DNS 配置,而是指定特定的 DNS 服务器(如 8.8.8.8)。

evdns_base_nameserver_ip_add(dns_base, "8.8.8.8");

3.2. 搜索域 (Search Domains)

支持处理 /etc/resolv.conf 中的 search 指令,自动补全域名后缀。

4. 总结

在高性能网络编程中,永远不要在 Event Loop 中调用阻塞函数。DNS 解析是最大的隐患之一。使用 evdns,让你的程序在解析域名的同时,依然能流畅地处理成千上万个并发连接。


上一篇: 05-protocols/http-server.md - 内置 HTTP Server 下一篇: 05-protocols/modern-web.md - 现代 Web 协议集成

返回 Libevent 专题索引


By .