Android Socket编程-DNS

255 阅读2分钟

DNS 解析

    DNS解析,其实就是找到域名对应的IP地址,这里是一对多的关系,一个域名可以注册多个IP地址,比如百度(www.baidu.com), 它具有很多服务器,所以DNS解析可以拿到很多IP。     

对于域名和IP的映射关系是存储在哪里呢?

  1. 客户端浏览器
  2. 客户端持久化缓存
  3. 本地网络域名服务器
  4. 根域名服务器

    对于一个网络请求,如果我们输入的是域名,那么系统会先对该域名进行DNS解析,解析流程如下:

DNS解析流程 (1).png

    对于返回的多个IP结果,DNS服务器并不会进行排序。Android 会遍历尝试这些结果,直到找到一个可以正常访问的IP。

手动对域名进行解析

    可能很多时候,我们想要拿到一个域名的IP服务地址,那么怎么拿到呢?

    Android提供了对应的API,让我们可以轻易进行DNS解析,拿到目标地址。

InetAddress inetAddress = InetAddress.getByName("ww.baidu.com")
byte[] ipAddress = inetAddress.getAddress();
String ipString = InetAddress.getByAddress(ipAddress).getHostAddress();

    通过上述方法就可以拿到目标IP地址。

修改DNS解析默认域名服务器

    对于APP来说,可以连接不同网络,连接的网络不同,那么在进行DNS解析时候,请求的根域名服务器就不同。因为不同的网络设置的DNS服务器地址不一样。

    可能我们需要修改我们当前想要进行DNS请求的目标服务器。

    在Android Q以上,官方也提供了API:

ConnectivityManager conn = getSystemService(ConnectivityManager.class);
LinkProperties linkProperties = conn.getLinkProperties(conn.getActiveNetwork());

// 获取当前网络的DNSServer服务
List<InetAddress> ll = linkProperties.getDnsServers();

// 通过 setDnsServers 来设置我们自己的server
linkProperties.setDnsServers(Collections.singleton(InetAddress.getByName("ww.baidu.com")));

三方包DNS解析

    对于不依赖Android系统DNS解析方法,那么可以集成三方JAR包,dnsjava 来进行DNS解析。

// 创建DNS解析器
Resolver resolver = new SimpleResolver("8.8.8.8"); 

// 查询DNS记录
Name name = Name.fromString("www.example.com.");
Record record = Record.newRecord(name, Type.A, DClass.IN);
Message query = Message.newQuery(record);
Message response = resolver.send(query);

// 解析响应
Record[] answers = response.getSectionArray(Section.ANSWER);
for (Record answer : answers) {
   if (answer instanceof ARecord) {
        ARecord aRecord = (ARecord) answer;
        System.out.println("IP Address: " + aRecord.getAddress());
    }
}

具体可以参考其GitHub官网:github.com/dnsjava/dns…