无论是从 Local DNS 解析域名,获取到 IP 列表,还是从第三方的 DNS 解析服务中,获取到域名对应的 IP 列表。我们获得多个 IP 后,总是想选取一个最优的 IP 使用,本文主要探讨如何在客户端探测 IP 的连接性以及连接速度,保证返回可用性最好的IP,以达到“IP优选”的目的。
新浪开源一个 HTTPDNSLib ,里面包含了测速逻辑,GitHub地址如下:
<a href="https://github.com/CNSRE/HTTPDNSLib-for-iOS">《HTTPDNSLib-for-iOS》</a>
<a href="https://github.com/CNSRE/HTTPDNSLib">《HTTPDNSLib》</a>
我们以该 sdk 里的测速逻辑为例进行原理解析。
使用 linux socket connect 和 select 函数实现的。 基于以下原理:
即使套接口是非阻塞的。如果连接的服务器在同一台主机上,那么在调用connect 建立连接时,连接通常会立即建立成功,我们必须处理这种情况。
源自Berkeley的实现(和Posix.1g)有两条与select 和非阻塞IO相关的规则:
A. 当连接建立成功时,套接口描述符变成可写;
B. 当连接出错时,套接口描述符变成既可读又可写。
详细的测速实现如下,原理参考注释:
以 iOS 实现为例: