1 为什么要自己解析?
典型场景 | 说明 |
---|---|
劫持/污染检测 | 比较 系统解析 与 自建 DNS 的差异 |
QoS / CDN 选路 | 对每个候选 IP 做 RT/丢包测速 |
系统 API(NSURLSession
/ Network.framework
)在「真正建立连接之前」不会把解析结果暴露出来,因此需要主动解析一步。
2 API 选型概览
API | 是否过时 | 线程模型 | 返回 IPv4/6 | 备注 | |
---|---|---|---|---|---|
getaddrinfo | ❌ | 阻塞,需要自己放到队列 | ✔︎ | POSIX,底层稳定 | |
CFHost | ✅ iOS 15 标记为 Deprecated | RunLoop + 回调 | ✔︎ | 仅维护旧代码时可用 | |
Network.framework (NWConnection ) | — | 建立连接后才能拿到 endpoint | 仅在已连通后 | 不适合「只解析」 | |
SCNetworkReachability | — | 回调 | ✗ | 只能拿到 是否可达,不给 IP |
结论:2025 年仍推荐
getaddrinfo
—— 标准、安全、跨平台;若真要用 CFHost 必须接受弃用风险。
3 getaddrinfo —— 最硬核也最好用
3.1 Objective-C 同步示例
+ (NSArray<NSString *> *)pug_resolve:(NSString *)hosterror:(NSError **)error {struct addrinfo hints = {0}, *res = NULL;hints.ai_family = AF_UNSPEC; // 同时拿到 IPv4 + IPv6hints.ai_socktype = SOCK_STREAM; // TCP/UDP 都行int gai = getaddrinfo(host.UTF8String, NULL, &hints, &res);if (gai != 0) {if (error) *error = [NSError errorWithDomain:NSPOSIXErrorDomaincode:gaiuserInfo:@{NSLocalizedDescriptionKey:@(