HttpClient与HttpURLConnection结合HttpDns的实践指南

更新:11-16 民间故事 我要投稿 纠错 投诉

核心代码位于java.net.InetAddress.lookupHostByName(String host, int netId)

公共类InetAddress 实现可序列化{

.

/**

* 使用缓存将主机名解析为其IP 地址。

*

* @param host 要解析的主机名。

* @param netId 要执行解析的网络。

* @return 主机的IP地址。

*/

私有静态InetAddress[] LookupHostByName(String host, int netId)

抛出UnknownHostException {

BlockGuard.getThreadPolicy().onNetwork();

//我们有缓存结果吗?

对象cachedResult=addressCache.get(host, netId);

if (cachedResult !=null) {

if (cachedResult instanceof InetAddress[]) {

//缓存的肯定结果。

返回(InetAddress[]) 缓存结果;

} 别的{

//缓存的负结果。

抛出新的UnknownHostException((字符串)cachedResult);

}

}

尝试{

StructAddrinfo 提示=new StructAddrinfo();

提示.ai_flags=AI_ADDRCONFIG;

提示.ai_family=AF_UNSPEC;

//如果我们不指定套接字类型,每个地址都会出现两次,一次

//用于SOCK_STREAM,一个用于SOCK_DGRAM。既然我们不归还家人

//无论如何,只选一个。

提示.ai_socktype=SOCK_STREAM;

InetAddress[] 地址=Libcore.os.android_getaddrinfo(host,hints,netId);

//TODO: getaddrinfo 应该设置它返回的InetAddresses 的主机名吗?

for (InetAddress 地址: 个地址) {

地址.主机名=主机;

}

addressCache.put(主机、netId、地址);

返回地址;

} catch (GaiException gaiException) {

.

}

}

}其中addressCache是InetAddress的本地缓存:

私有静态最终地址缓存地址缓存=新地址缓存();结合InetAddress的解析策略,我们可以通过以下方法实现自定义DNS服务:

通过HttpDns SDK获取目标域名的IP,并使用反射获取InetAddress.addressCache对象。使用反射调用addressCache.put()方法。将域名和IP的对应关系写入InetAddress缓存中。具体实现可以参考如下代码:

公共类CustomDns {

公共静态无效writeSystemDnsCache(字符串主机名,字符串ip){

尝试{

类inetAddressClass=InetAddress.class;

字段字段=inetAddressClass.getDeclaredField("addressCache");

字段.setAccessible(true);

对象对象=field.get(inetAddressClass);

类cacheClass=object.getClass();

方法put 方法;

if(Build.VERSION.SDK_INT=Build.VERSION_CODES.LOLLIPOP) {

//api21及以上的put方法为put(String host, int netId, InetAddress[] address)

putMethod=cacheClass.getDeclaredMethod("put", String.class, int.class, InetAddress[].class);

} 别的{

//api20及以下的put方法为put(String host, InetAddress[] address)

putMethod=cacheClass.getDeclaredMethod("put", String.class, InetAddress[].class);

}

putMethod.setAccessible(true);

String[] ipStr=ip.split("\.");

byte[] ipBuf=新字节[4];

for(int i=0; i 4; i++) {

ipBuf[i]=(字节) (Integer.parseInt(ipStr[i])0xff);

}

if(Build.VERSION.SDK_INT=Build.VERSION_CODES.LOLLIPOP) {

putMethod.invoke(object, hostName, 0, new InetAddress[] {InetAddress.getByAddress(ipBuf)});

} 别的{

putMethod.invoke(object, hostName, new InetAddress[] {InetAddress.getByAddress(ipBuf)});

}

} catch (NoSuchFieldException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (NoSuchMethodException e) {

e.printStackTrace();

} catch (UnknownHostException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

}

}

}与一般方案相比,使用该方法有以下优点:

该方案实现简单,通用性强,适用于HTTPS、SNI、cookie设置等场景。避开证书验证、域名检查等环节,全球生效。 InetAddress.addressCache 是一个全局单例。该方案对所有使用InetAddress作为域名解析服务的请求生效。另外,使用该方案时请务必注意以下几点:

AddressCache默认TTL为2S,默认最多可保存16条缓存记录:

类地址缓存{

.

/**

* 当缓存包含的条目多于此时,我们开始删除最旧的条目。

* 这应该是2 的幂,以避免自定义地图中浪费空间。

*/

私有静态最终int MAX_ENTRIES=16;

//Java级缓存的TTL很短,只有2s。

私有静态最终长TTL_NANOS=2 * 1000000000L;

}

}Android虚拟机下的反射规则与JVM中不同,不能直接修改final变量的值。因此,使用该方法时请务必注意IP过期时间和缓存数量。另外,可以尝试另一种解决这个问题的方法:重写AddressCache类,先通过ClassLoader加载,覆盖系统类。

API 21 中更改了AddressCache.put 方法,并添加了netId 参数。为了保证兼容性,需要针对不同的版本进行不同的处理。具体解决方法可以参考上面的代码

文章分享结束,HttpClient与HttpURLConnection结合HttpDns的实践指南和的答案你都知道了吗?欢迎再次光临本站哦!

用户评论

南初

我一直在使用 HttpClient 和 HttpUrlConnection ,学习一下最佳实践希望能提高效率!

    有11位网友表示赞同!

神经兮兮°

httpdns确实可以加速访问,这篇文章讲得怎么样?

    有6位网友表示赞同!

我绝版了i

要学起来HttpClient和HttpURLConnection啊,太久了!

    有17位网友表示赞同!

疲倦了

做android开发的必备技能,好好看看这份最佳实践。

    有6位网友表示赞同!

淡抹丶悲伤

平时在项目中都是直接用这两个,没想过有这么多小技巧!

    有12位网友表示赞同!

有你,很幸福

HttpDns能提高请求速度?这篇文章来帮帮忙啊!

    有7位网友表示赞同!

封心锁爱

想优化网络请求的流程?就看这份最佳实践了!

    有19位网友表示赞同!

我就是这样一个人

做web开发也有人用这些工具吧,还是看看区别。

    有17位网友表示赞同!

灬一抹丶苍白

学习新的知识总是一件好事,期待一篇干货满满的文章!

    有13位网友表示赞同!

苏樱凉

希望能学到一些新的调试技巧,这样处理网络请求就更方便了!

    有11位网友表示赞同!

执念,爱

最近在学习Android开发,感觉HttpClient和HttpUrlConnection很有用,赶紧看看最佳实践!

    有16位网友表示赞同!

*巴黎铁塔

希望文章能讲清楚一些使用场景,方便我根据实际项目来应用.

    有14位网友表示赞同!

残留の笑颜

想了解一下HttpDns如何提高http请求效率?

    有17位网友表示赞同!

羁绊你

有没有什么好的工具可以帮助我们测试HttpClient和HttpUrlConnection的性能?

    有18位网友表示赞同!

歇火

这种最佳实践对不同网络环境有没有适用性差异?

    有13位网友表示赞同!

酒笙倾凉

好文章,分享一下给其他也在做Android开发的小伙伴!

    有11位网友表示赞同!

那伤。眞美

希望能了解更多关于HttpClient 和 HttpUrlConnection 的详细介绍。

    有15位网友表示赞同!

暮光薄凉

学习新的东西总能让我感觉更有动力!

    有18位网友表示赞同!

无寒

赶紧把这篇文章收藏起来,以后有需要的直接就来翻阅一遍了!

    有18位网友表示赞同!

【HttpClient与HttpURLConnection结合HttpDns的实践指南】相关文章:

1.蛤蟆讨媳妇【哈尼族民间故事】

2.米颠拜石

3.王羲之临池学书

4.清代敢于创新的“浓墨宰相”——刘墉

5.“巧取豪夺”的由来--米芾逸事

6.荒唐洁癖 惜砚如身(米芾逸事)

7.拜石为兄--米芾逸事

8.郑板桥轶事十则

9.王献之被公主抢亲后的悲惨人生

10.史上真实张三丰:在棺材中竟神奇复活

上一篇:双11与双12优惠对比:哪个活动更划算? 下一篇:Nature Methods:空间转录组与单细胞转录组整合分析工具性能评估