Android中DNS解析

原文链接  http://bbs.9ria.com/thread-247917-1-1.html


当服务端IP变化,大量用户还是访问的以前的IP,连接不上服务器。
  我们的客户端软件如何通过域名正确访问服务器?这里面主要涉及到DNS缓存的问题。
  什么是DNS?
  DNS 是域名系统 (Domain Name System) 的缩写,是因特网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。简单说,DNS就是 域名(我们平时使用的网址,如www.sina.com.cn等)到 ip 地址的 服务器。
  因为计算机访问对方服务器时,只能识别对方服务器的ip地址,所以当我们输入网址时,就需要先到DNS服务器查询对应的IP地址,然后再访问。
  DNS缓存
  DNS访问是个比较耗时的操作,所以android会把查询到的结果缓存起来,下次查询的时候,就可以直接从缓存中获取,而不需要DNS查询。
  DNS解析缓存分为两种:查询成功的缓存,查询失败的缓存(如查询域名不存在等) 。
  android 系统对DNS缓存 有两个地方,一个是虚拟机层 , 一个是 框架层 java.net.InetAddress 类内部维护了一个缓存。
  当通过域名解析IP地址时,通过 java.net.InetAddress类来调用相应的方法。它会先查看自身缓存里有没有,木有的话会看虚拟机层有木有缓存,还木有的话才会到DNS服务器查询。
  控制DNS缓存
  有些情况下,我们不能使用DNS缓存,如服务器IP地址变化等。
  虚拟机层默认使用的缓存策略是 成功的查询永久缓存(这里的永久缓存是指整个虚拟机生命周期,虚拟机重启,缓存就没有了) , 失败的查询只缓存10s。
  我们可以设置虚拟机的DNS缓存时间TTL (time-to-live 生命周期):
  java代码

  1. Security.setProperty("networkaddress.cache.ttl", 
  2. String.valueOf(0));

  3.   Security.setProperty("networkaddress.cache.negative.ttl", 
  4. String.valueOf(0));
复制代码
  "networkaddress.cache.ttl"表示查询成功的缓存,"networkaddress.cache.negative.ttl"表示查询失败的缓存。第二个参数表示缓存有效时间,单位是秒。
  时间 -1 表示永久缓存,0 表示从不缓存,其他表示缓存具体有效时间。
  java.net.InetAddress内部的缓存我们没有办法控制。4.0以前是永久缓存,4.0以后是只缓存2s。也就是说4.0以前通过设置虚拟机TTL没有用,因为java.net.InetAddress永久缓存了。
  下面是android api InetAddress 里的原话:
  DNS caching
  In Android 4.0 (Ice Cream Sandwich) and earlier, DNS caching was performed both by InetAddress and by the C library, which meant that DNS TTLs could not be honored correctly.In later releases, caching is done solely by the C library and DNS TTLs are honored.
  在控制DNS缓存时有两点需要注意:
  1. 可以根据实际情况来设置networkaddress.cache.ttl属性的值。一般将这个属性的值设为-1.但如果访问的是动态映射的域名(如使用动态域名服务将域名映射成ADSL的动态IP), 就可能产生IP地址变化后,客户端得到的还是原来的IP地址的情况。
  2. 在设置networkaddress.cache.negative.ttl属性值时最好不要将它设为-1,否则如果一个域名因为暂时的故障而无法访问,那么程序再次访问这个域名时,即使这个域名恢复正常,程序也无法再访问这个域名了。除非重新运行程序。
  IP变化解决方案
  当服务端IP变化,我们的软件又必须通过域名正确访问服务器。
  最简单且通用的解决办法是,重启应用程序。
  但是我们没有办法控制用户的行为,用户要是不停止程序的话,就永远连不上。
  解决方案1:在 Application 的 onCreate()里设置虚拟机不缓存DNS。
  假设用户此时正在使用我们的软件,此时域名改变IP指向,用户断线重连后会获得正确的IP,成功连接。InetAddress 缓存的那2s可以不考虑了。
  缺点:4.0下不管用。
  解决方案2:在第一次域名解析成功后,将IP地址存到文件里。下次连接的时候优先使用保存的IP地址,只有当IP地址连接不上时,才进行域名解析,解析成功后,再次保存IP。
  方案一加方案二一起解决了大多数用户的问题。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: OkHttp是一个用于Android和Java应用程序的HTTP客户端库。当使用OkHttp进行网络请求时,它会自动解析主机名并将其转换为IP地址。这个过程被称为DNS解析。默认情况下,OkHttp使用系统默认的DNS解析器来解析主机名。 但是,你也可以使用自定义的DNS解析器来替换系统默认的DNS解析器。这可以通过OkHttp的Dns接口实现。你只需要实现Dns接口并将其传递给OkHttpClient即可。 例如,你可以创建一个自定义的DNS解析器,它将所有主机名解析为特定的IP地址: ``` public class CustomDns implements Dns { private static final InetAddress[] CUSTOM_IPS = new InetAddress[] { InetAddress.getByName("192.168.0.1"), InetAddress.getByName("192.168.0.2") }; @Override public List<InetAddress> lookup(String hostname) throws UnknownHostException { return Arrays.asList(CUSTOM_IPS); } } ``` 然后,你可以将这个自定义的DNS解析器传递给OkHttpClient: ``` OkHttpClient client = new OkHttpClient.Builder() .dns(new CustomDns()) .build(); ``` 这样,在进行网络请求时,OkHttp将使用你自定义的DNS解析器来解析主机名。 ### 回答2: OkHttp DNS 是 OkHttp 框架的一部分,用于处理网络请求时解析域名的功能。 在进行网络请求时,我们通常会使用域名来表示目标主机,如 "www.example.com"。然而,计算机网络通信实际上是通过 IP 地址进行的。因此,我们需要将域名解析为对应的 IP 地址,以便与服务器进行通信。 OkHttp DNS 提供了一种机制,可以自定义和配置域名解析的策略。它允许开发人员替换默认的 DNS 解析器,从而实现更高效、灵活的域名解析。 OkHttp 内置了一个默认的 DNS 解析器,它使用 Java 标准库的 InetAddress 类来解析 IP 地址。然而,对于某些特定的场景和需求,我们可能需要使用其他的 DNS 解析器。 通过实现自定义的 Dns 接口,我们可以将其传递给 OkHttp,从而替换默认的 DNS 解析器。我们可以自己实现域名解析的逻辑,例如在本地存 IP 地址、使用其他第三方 DNS 解析库等。这样可以提高解析效率、减少网络请求的延迟。 在使用 OkHttp DNS 时,我们可以通过 OkHttpClient.Builder 类的 dns() 方法来设置自定义的 DNS 解析器。例如: Dns customDns = new CustomDns(); OkHttpClient client = new OkHttpClient.Builder() .dns(customDns) .build(); 通过上述代码,我们将自定义的 DNS 解析器 customDns 设置为 OkHttpClient 的属性。在后续的网络请求,OkHttp 将使用该解析器来解析域名。 总之,OkHttp DNS 提供了灵活、可定制的域名解析策略,可以满足不同场景下的需求,提升网络请求的性能。 ### 回答3: OkHttp是一个开源的轻量级的HTTP客户端库,主要用于Android平台。它提供了一组接口来发送和接收HTTP请求和响应数据,并且支持各种常见的HTTP协议和功能。 OkHttp DNS是OkHttp库提供的一个功能,用于解析主机名(域名)并将其转换为IP地址。DNS(Domain Name System)是互联网用于将域名转换为IP地址的系统,它允许我们使用域名来访问Web服务器,而不是直接使用IP地址。 OkHttp默认使用系统的DNS解析服务来解析主机名。但是,OkHttp也提供了自定义DNS功能,使我们可以根据需要修改或扩展DNS解析的过程。 通过使用OkHttp DNS,我们可以实现以下功能: 1. 自定义DNS解析:我们可以使用自定义的DNS解析服务来解析主机名。这对于需要使用特定的DNS服务器或实现一些自定义逻辑的应用程序非常有用。 2. 域名解析优化:OkHttp DNS还可以实现域名解析的优化。例如,我们可以存最近解析的域名,以便下次访问时可以更快地获取IP地址。这可以提高应用程序的性能和响应速度。 3. DNS解析故障处理:如果默认的DNS解析服务发生故障或无法解析某个域名,我们可以使用OkHttp DNS来处理这些错误情况。例如,我们可以在DNS解析失败时使用备用的DNS服务器。 总之,OkHttp DNS是一个非常有用的功能,它可以让我们更灵活地处理主机名的解析,并提供更好的性能和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值