Java动态替换InetAddress中DNS的做法简单分析2

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.InputStreamReader;
  5. import java.lang.reflect.Field;
  6. import java.lang.reflect.Method;
  7. import java.net.HttpURLConnection;
  8. import java.net.InetAddress;
  9. import java.net.MalformedURLException;
  10. import java.net.URL;
  11. import java.net.UnknownHostException;
  12. import java.util.HashMap;
  13. import java.util.List;
  14. import java.util.Map;
  15. import sun.net.spi.nameservice.NameService;
  16. public class JavaDNSCacheTest {
  17. /**
  18. * 经测试,二种方式在Windows环境都可以, Linux环境待测
  19. *
  20. * @param args
  21. * @throws Exception
  22. */
  23. public static void main(String[] args) throws Exception {
  24. /* 1. 动态替换AddressCache */
  25. // changeDNSWithAddressCache();
  26. /* 1. 动态代理NameService */
  27. changeDNSWithNameService();
  28. }
  29. public static void changeDNSWithNameService() throws Exception {
  30. /* 1. 获取反身类 */
  31. Class<?> addressClass = InetAddress.class;
  32. /* 2. 获取addressCache字段 */
  33. try {
  34. Field nameServiceField = addressClass.getDeclaredField("nameService");// 对于Jrockit或IBM JDK
  35. nameServiceField.setAccessible(true);
  36. sun.net.spi.nameservice.NameService nameService = (NameService) nameServiceField.get(null);
  37. nameServiceField.set(null, new NameServiceProxy(nameService));
  38. nameServiceField.setAccessible(false);
  39. } catch (NoSuchFieldException e) {
  40. Field nameServicesField = addressClass.getDeclaredField("nameServices");// 对于OpenJDK
  41. nameServicesField.setAccessible(true);
  42. List<sun.net.spi.nameservice.NameService> nameServices = (List<sun.net.spi.nameservice.NameService>) nameServicesField.get(null);
  43. if (nameServices != null && nameServices.size() > 0) {
  44. /* 置换为代理实例 */
  45. nameServices.set(0, new NameServiceProxy(nameServices.get(0)));
  46. } else {
  47. // 可能为空吗? 待测
  48. }
  49. nameServicesField.setAccessible(false);
  50. }
  51. getHttpConent("www.baidu.com");
  52. }
  53. public static void changeDNSWithCddressCache() throws Exception {
  54. /* 1. 获取反身类 */
  55. Class<?> addressClass = InetAddress.class;
  56. /* 2. 获取addressCache字段 */
  57. Field addressCacheField = addressClass.getDeclaredField("addressCache");
  58. /* 3. 获取addressCache */
  59. addressCacheField.setAccessible(true);
  60. Object addressCache = addressCacheField.get(null);
  61. addressCacheField.setAccessible(false);
  62. /* 4. 获取addressCache的反射类 */
  63. Class<?> addressCacheClass = addressCache.getClass();
  64. /* 5. 获取addressCache的put方法 */
  65. Method putMethod = addressCacheClass.getDeclaredMethod("put", String.class, InetAddress[].class);
  66. /* 5. 修改addressCache将wwww.baidu.com换成指定任意IP */
  67. putMethod.setAccessible(true);
  68. putMethod.invoke(addressCache, "www.baidu.com", new InetAddress[] { InetAddress.getByAddress(new byte[] { 115, (byte) 239, (byte) 210, 26 }) });
  69. putMethod.setAccessible(false);
  70. /* 6.测试,看看是否连通 */
  71. getHttpConent("www.baidu.com");
  72. }
  73. private static void getHttpConent(String host) throws MalformedURLException, IOException {
  74. HttpURLConnection conn = (HttpURLConnection) new URL("http://" + host).openConnection();
  75. try {
  76. conn.setConnectTimeout(3000);// 减少连接时间,方便测试
  77. conn.setDefaultUseCaches(false);
  78. conn.setDoInput(true);
  79. conn.setRequestMethod("GET");
  80. conn.connect();
  81. int code = conn.getResponseCode();
  82. System.out.format("REST[%d]\n", code);
  83. InputStream in = null;
  84. in = conn.getErrorStream();// 如果非2xx,则由errorStream获取输出.
  85. if (in == null) {
  86. in = conn.getInputStream();
  87. }
  88. if (in != null) {
  89. BufferedReader reader = new BufferedReader(new InputStreamReader(in));
  90. for (String line = null; (line = reader.readLine()) != null;) {
  91. System.out.println(line);
  92. }
  93. }
  94. } finally {
  95. if (conn != null) {
  96. conn.disconnect();
  97. }
  98. }
  99. }
  100. @SuppressWarnings("restriction")
  101. public static class NameServiceProxy implements sun.net.spi.nameservice.NameService {
  102. final sun.net.spi.nameservice.NameService nameService;
  103. final Map<String, InetAddress[]> mapping = new HashMap<String, InetAddress[]>();
  104. {
  105. try {
  106. mapping.put("www.baidu.com", new InetAddress[] { InetAddress.getByAddress(new byte[] { 115, (byte) 239, (byte) 210, 26 }) });
  107. } catch (UnknownHostException e) {
  108. e.printStackTrace();
  109. }
  110. }// 实例初始化表
  111. public NameServiceProxy(sun.net.spi.nameservice.NameService nameService) {
  112. this.nameService = nameService;
  113. }
  114. @Override
  115. public String getHostByAddr(byte[] addr) throws UnknownHostException {
  116. return this.nameService.getHostByAddr(addr);
  117. }
  118. @Override
  119. public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException {
  120. if (mapping.containsKey(host)) {
  121. return mapping.get(host);
  122. } else {
  123. return this.nameService.lookupAllHostAddr(host);
  124. }
  125. }
  126. }
  127. }
时间: 2024-08-30 02:43:36

Java动态替换InetAddress中DNS的做法简单分析2的相关文章

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,

WebRTC中的AppRTCDemo.apk简单分析

以前一直在QQ空间记录一些简单的关于webrtc的笔记.博说不如发布CSDN,想想也可以,解决了一些小问题,也可以帮助一下其它碰到该同样问题的人. 上周试着将WebRTC中的PeerConnection_client进行改写,拿 掉了PeerConnection_Server端,改用openfire服务器,信令采用xmpp,主要代码来源于call.主要还是将http请求用xmpp重写了,原理上很简单,合并后,效果还可以. 现在开始看android版本的peerconnection,也就是标题的A

java程序替换word2007中的图片

1.新建word2007文档h2do.docx: 2.QQ截图粘贴到文档,添加些文字: 3.用winrar打开(修改扩展名docx为rar或右键->打开方式->选择winrar程序),目录结构如下: . │  [Content_Types].xml │ ├─docProps │      app.xml │      core.xml │ ├─word │  │  comments.xml │  │  document.xml │  │  endnotes.xml │  │  fontTabl

maven项目动态替换配置中的值

为何一些maven项目可以替换配置文件中的变量? 比如说一个log4j.properties文件中: logFolder=${log4j.folder} BufferedIO=${log4j.bufferedIO} ImmediateFlush=${log4j.immediateFlush} # 根日志(没有指定自定义logger的会使用此配置) 日志等级阀门在此 #debug log4j.rootLogger=info,commonLog,errorLog 变量${log4j.folder}?

java.util.ComparableTimSort中的sort()方法简单分析

TimSort算法是一种起源于归并排序和插入排序的混合排序算法,设计初衷是为了在真实世界中的各种数据中能够有较好的性能. 该算法最初是由Tim Peters于2002年在Python语言中提出的. TimSort 是一个归并排序做了大量优化的版本号. 对归并排序排在已经反向排好序的输入时表现O(n2)的特点做了特别优化.对已经正向排好序的输入降低回溯.对两种情况混合(一会升序.一会降序)的输入处理比較好. 在jdk1.7之后.Arrays类中的sort方法有一个分支推断,当LegacyMerge

【Flume】flume中通道channel的简单分析梳理

Channels are the repositories where the events are staged on a agent. Source adds the events and Sink removes it. 通道就是事件暂存的地方,source负责往通道中添加event,sink负责从通道中移出event flume1.5.2内置的通道有:内存,文件,jdbc 1.内存通道memory-channel 时间存储在内存队列中,对于性能要求高且能接受agent失败时数据丢失的情况

java动态代理实现与原理详细分析

一.代理模式代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务.简单的说就是,我们在访问实际对象时,是通过代理对象来访问的,代理模式就是在访问实际对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途.在后面我会 解释这种间

Java动态代理原理

关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理. 一.代理模式    代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务.简单的说就是

Java动态代理 深度详解

代理模式是设计模式中非常重要的一种类型,而设计模式又是编程中非常重要的知识点,特别是在业务系统的重构中,更是有举足轻重的地位.代理模式从类型上来说,可以分为静态代理和动态代理两种类型. 今天我将用非常简单易懂的例子向大家介绍动态代理的两种类型,接着重点介绍动态代理的两种实现方式(Java 动态代理和 CGLib 动态代理),最后深入剖析这两种实现方式的异同,最后说说动态代理在我们周边框架中的应用. 在开始之前,我们先假设这样一个场景:有一个蛋糕店,它们都是使用蛋糕机来做蛋糕的,而且不同种类的蛋糕