• 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] ", 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. }
  • 相关阅读:
    光学显微镜孔径光阑的正确使用
    win10c盘上的回收站已损坏
    Linux回顾【2】shell
    git 更新远端分支信息
    Linux回顾【3】文本编辑器 (vim/nano)
    C#面向抽象编程第二讲
    php7:给已编译安装版本增加一个编译参数(PHP 7.4.2)
    各种数值计算相关的问题
    告警运维中心|构建高效精准的告警协同处理体系
    CNCF 沙箱项目 OCM Placement 多集群调度指南
  • 原文地址:https://www.cnblogs.com/zolo/p/5849244.html
Copyright © 2020-2023  润新知