Java动态替换InetAddress中DNS的做法简单分析1
在java.net包描述中, 简要说明了一些关键的接口. 其中负责networking identifiers的是Addresses. 这个类的具体实现类是InetAddress, 底层封装了Inet4Address与Inet6Address的异同, 可以看成一个Facade工具类.
- A Low Level API, which deals with the following abstractions:
- Addresses, which are networking identifiers, like IP addresses.
- Sockets, which are basic bidirectional data communication mechanisms.
- Interfaces, which describe network interfaces.
复制代码
在OpenJDK的InetAddress源码中, 根据dns或hostname解析IP的代码部分:
- private static InetAddress[] getAllByName0 (String host, InetAddress reqAddr, boolean check)
- throws UnknownHostException {
- /* If it gets here it is presumed to be a hostname */
- /* Cache.get can return: null, unknownAddress, or InetAddress[] */
- /* make sure the connection to the host is allowed, before we
- * give out a hostname
- */
- if (check) {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkConnect(host, -1);
- }
- }
- InetAddress[] addresses = getCachedAddresses(host);
- /* If no entry in cache, then do the host lookup */
- if (addresses == null) {
- addresses = getAddressesFromNameService(host, reqAddr);
- }
- if (addresses == unknown_array)
- throw new UnknownHostException(host);
- return addresses.clone();
- }
复制代码
关键的二个方法是:
getCachedAddresses(host);
getAddressesFromNameService(host, reqAddr);
前者从addressCache, 或negativeCache根据dns/hostname解析缓存的IP.
后者从遍历nameServices,调用每个NameService的lookupAllHostAddr(host)查找IP, 然后将host:IP缓存到前面的cache中.
根据上述, 实现动态解析DNS, 有二种方式:
1. 反射addressCache, 或negativeCache, 将host:IP通过Cache的put()方法放入.
2. 反射nameServices,将代理的NameService实例放入.
二种做法的难处:
1. addressCache, 或negativeCache都是 java.net.InetAddress.Cache, 其内部的CacheEntry受二组JVM选项影响:
networkaddress.cache.ttl
networkaddress.cache.negative.ttl
在ttl后, CacheEntry的get()只会返回null.
2. nameServices只是OpenJDK的实现. 换言之,只是SUN一家的. 其他JDK不用此属性名.
写段代码看看Jrockit与IBM JVM中InetAddress内部的属性:
- Class<InetAddress> type = InetAddress.class;
- Field[] fields = type.getDeclaredFields();
- for (Field f : fields) {
- System.out.println(f.getName() + ":" + f.getType());
- }
复制代码
OpenJDK:
- IPv4
- IPv6
- preferIPv6Address
- holder
- nameServices
- canonicalHostName
- serialVersionUID
- addressCache
- negativeCache
- addressCacheInit
- unknown_array
- impl
- lookupTable
- cachedLocalHost
- cacheTime
- maxCacheTime
- cacheLock
- FIELDS_OFFSET
- UNSAFE
- serialPersistentFields
- $assertionsDisabled
复制代码
JRockit:
- IPv4
- IPv6
- preferIPv6Address
- hostName
- address
- family
- nameService
- canonicalHostName
- serialVersionUID
- addressCache
- negativeCache
- addressCacheInit
- unknown_array
- impl
- lookupTable
- $assertionsDisabled
复制代码
IBM JDK
- IPv4:int
- IPv6:int
- preferIPv6Address
- hostName:class java.lang.String
- address:int
- family:int
- nameService:interface sun.net.spi.nameservice.NameService
- canonicalHostName:class java.lang.String
- serialVersionUID:long
- addressCache:class java.net.InetAddress$Cache
- negativeCache:class java.net.InetAddress$Cache
- localHostName:class java.lang.String
- localHostNameLock:class java.lang.Object
- cacheLocalHost:boolean
- addressCacheInit:boolean
- unknown_array:class [Ljava.net.InetAddress;
- impl:interface java.net.InetAddressImpl
- lookupTable:class java.util.HashMap
- $assertionsDisabled:boolean
复制代码
看到这里, 知道蛋疼了吧. 三种JDK中,
OpenJDK中是nameservices是个List<NameService>,
Jrockit与IBM JVM中却是nameservice, 只是单独的NameService实例.
所以要用第2种做法, 你至少要满足这三种主流JDK的需求.
简单实现二种做法:
做法1, 动态替换AddressCache.
做法2, 动态代理NameService.
源码如下
- 长度限制, 源码查看回贴.
复制代码
暂时测试到这吧, 有兴趣的同学可以一起完善. 争取同时满足OpenJDK, Jrockit, IBM JDK三种主流环境的DNS动态解析类.
Java动态替换InetAddress中DNS的做法简单分析1的更多相关文章
- Java动态替换InetAddress中DNS的做法简单分析2
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...
- java itext替换PDF中的文本
itext没有提供直接替换PDF文本的接口,我们可以通过在原有的文本区域覆盖一个遮挡层,再在上面加上文本来实现. 所需jar包: 1.先在PDF需要替换的位置覆盖一个白色遮挡层(颜色可根据PDF文字背 ...
- Java动态代理——框架中的应用场景和基本原理
前言 之前已经用了5篇文章完整解释了java动态代理的原理,本文将会为这个系列补上最后一块拼图,展示java动态代理的使用方式和应用场景 主要分为以下4个部分 1.为什么要使用java动态代理 2.如 ...
- MessageFormat的用法,java动态替换String字符串中的占位符
import java.text.MessageFormat; import java.util.GregorianCalendar; import java.util.Locale; public ...
- 【Android】通过Java代码替换TabHost中的drawableTop资源
在博客 http://blog.csdn.net/jueblog/article/details/11837445 中的Tab选项卡中, 点击相应的Tab选项,图标没有发生改变. 这些资源图片也没有尽 ...
- Java动态调用类中方法
在Java中,调用类的方法有两种方式:对于静态方法可以直接使用类名调用,对于非静态方法必须使用类的对象调用.反射机制提供了比较另类的调用方式,可以根据需要指定要调用的方法,而不必在编程时确定.调用的方 ...
- Java 动态向 JTable 中添加数据
import java.awt.Toolkit; import javax.swing.SwingUtilities; import javax.swing.UIManager; import jav ...
- java.util.ComparableTimSort中的sort()方法简单分析
TimSort算法是一种起源于归并排序和插入排序的混合排序算法,设计初衷是为了在真实世界中的各种数据中能够有较好的性能. 该算法最初是由Tim Peters于2002年在Python语言中提出的. T ...
- java获取properties配置文件中某个属性最简单方法
假如我想获取src目录下sysConfig.properties中的uploadpath属性的值 方法如下所示: private static final ResourceBundle bundle ...
随机推荐
- JS 点击按钮后弹出遮罩层,有关闭按钮
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...
- Windows Server 2012下安装Hyper-V虚拟机
Windows Server 2012下安装Hyper-V虚拟机 Win server 2012系统中Hyper-V 性能进一步提高,广大爱好者都尝试体验它,可是有不少朋友无法正确安装虚拟机,尽管在网 ...
- 【SSH 1】SSH框架的基本理解
导读:在结束了BS之后,接触到的第一个项目算是网上商城了.这次用到了和之前都不一样的框架:SSH.这个项目就和之前学牛腩一样,有着里程碑的意义.当然了,这也就意味着,什么都是新鲜的,接触到的东西,有时 ...
- 跨域请求之JSONP 一
跨域请求之JSONP 一 跨域请求的方式有很多种, iframe document.domain window.name script XDomainRequest (IE8+) XMLHTTPReq ...
- SQL server 性能调优
转自: http://www.cnblogs.com/MR_ke/archive/2010/08/25/1807856.html sql 2005性能调优 SQL Server在运行一段时间,随着数据 ...
- Shiro使用总结
Shiro已经添加到项目中,现阶段管理两个功能: 1.身份验证:(已经能够满足现阶段需求) 2.权限管理: 权限管理,需要在界面中加一些标签,后台角色.资源的管理也需要整理好,然后在前端添加管理. 1 ...
- trap在shell中捕捉信号
一.trap捕捉到信号之后,可以有三种反应方式:(1)执行一段程序来处理这一信号(2)接受信号的默认操作(3)忽视这一信号 二.trap对上面三种方式提供了三种基本形式:第一种形式的trap命令在sh ...
- C++ 必知必会:条款16 指向成员函数的指针并非指针
这一点与指向成员的指针类似,其实现可能更加复杂,因为成员函数同时还存在虚拟函数,需要动态绑定执行动作.当然这种属性是属于函数本身的,此处表达的是指针不涉及函数的属性问题. 1: class shape ...
- vim与shell的切换
方法1: vim->shell: ctrl-z (挂起vim进程,相当于图形界面中的最小化) shell->vim: fg (foreground) 方法2: vim->shel ...
- Web服务器控件表
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAykAAAFRCAIAAAD/5nW4AAAgAElEQVR4nOydd3gVxfrHN6TXQ0KXEn