您的位置:首页 > 编程语言 > Java开发

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

2016-09-07 13:57 351 查看
import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

import java.net.HttpURLConnection;

import java.net.InetAddress;

import java.net.MalformedURLException;

import java.net.URL;

import java.net.UnknownHostException;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import sun.net.spi.nameservice.NameService;

public class JavaDNSCacheTest {

/**

* 经测试,二种方式在Windows环境都可以, Linux环境待测

*

* @param args

* @throws Exception

*/

public static void main(String[] args) throws Exception {

/* 1. 动态替换AddressCache */

// changeDNSWithAddressCache();

/* 1. 动态代理NameService */

changeDNSWithNameService();

}

public static void changeDNSWithNameService() throws Exception {

/* 1. 获取反身类 */

Class<?> addressClass = InetAddress.class;

/* 2. 获取addressCache字段 */

try {

Field nameServiceField = addressClass.getDeclaredField("nameService");// 对于Jrockit或IBM JDK

nameServiceField.setAccessible(true);

sun.net.spi.nameservice.NameService nameService = (NameService) nameServiceField.get(null);

nameServiceField.set(null, new NameServiceProxy(nameService));

nameServiceField.setAccessible(false);

} catch (NoSuchFieldException e) {

Field nameServicesField = addressClass.getDeclaredField("nameServices");// 对于OpenJDK

nameServicesField.setAccessible(true);

List<sun.net.spi.nameservice.NameService> nameServices = (List<sun.net.spi.nameservice.NameService>) nameServicesField.get(null);

if (nameServices != null && nameServices.size() > 0) {

/* 置换为代理实例 */

nameServices.set(0, new NameServiceProxy(nameServices.get(0)));

} else {

// 可能为空吗? 待测

}

nameServicesField.setAccessible(false);

}

getHttpConent("www.baidu.com");

}

public static void changeDNSWithCddressCache() throws Exception {

/* 1. 获取反身类 */

Class<?> addressClass = InetAddress.class;

/* 2. 获取addressCache字段 */

Field addressCacheField = addressClass.getDeclaredField("addressCache");

/* 3. 获取addressCache */

addressCacheField.setAccessible(true);

Object addressCache = addressCacheField.get(null);

addressCacheField.setAccessible(false);

/* 4. 获取addressCache的反射类 */

Class<?> addressCacheClass = addressCache.getClass();

/* 5. 获取addressCache的put方法 */

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

/* 5. 修改addressCache将wwww.baidu.com换成指定任意IP */

putMethod.setAccessible(true);

putMethod.invoke(addressCache, "www.baidu.com", new InetAddress[] { InetAddress.getByAddress(new byte[] { 115, (byte) 239, (byte) 210, 26 }) });

putMethod.setAccessible(false);

/* 6.测试,看看是否连通 */

getHttpConent("www.baidu.com");

}

private static void getHttpConent(String host) throws MalformedURLException, IOException {

HttpURLConnection conn = (HttpURLConnection) new URL("http://" + host).openConnection();

try {

conn.setConnectTimeout(3000);// 减少连接时间,方便测试

conn.setDefaultUseCaches(false);

conn.setDoInput(true);

conn.setRequestMethod("GET");

conn.connect();

int code = conn.getResponseCode();

System.out.format("REST[%d]\n", code);

InputStream in = null;

in = conn.getErrorStream();// 如果非2xx,则由errorStream获取输出.

if (in == null) {

in = conn.getInputStream();

}

if (in != null) {

BufferedReader reader = new BufferedReader(new InputStreamReader(in));

for (String line = null; (line = reader.readLine()) != null;) {

System.out.println(line);

}

}

} finally {

if (conn != null) {

conn.disconnect();

}

}

}

@SuppressWarnings("restriction")

public static class NameServiceProxy implements sun.net.spi.nameservice.NameService {

final sun.net.spi.nameservice.NameService nameService;

final Map<String, InetAddress[]> mapping = new HashMap<String, InetAddress[]>();

{

try {

mapping.put("www.baidu.com", new InetAddress[] { InetAddress.getByAddress(new byte[] { 115, (byte) 239, (byte) 210, 26 }) });

} catch (UnknownHostException e) {

e.printStackTrace();

}

}// 实例初始化表

public NameServiceProxy(sun.net.spi.nameservice.NameService nameService) {

this.nameService = nameService;

}

@Override

public String getHostByAddr(byte[] addr) throws UnknownHostException {

return this.nameService.getHostByAddr(addr);

}

@Override

public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException {

if (mapping.containsKey(host)) {

return mapping.get(host);

} else {

return this.nameService.lookupAllHostAddr(host);

}

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: