关于 Java 使用代理时的 DNS 解析问题!!!

红薯 发布于 2016/05/19 16:01
阅读 1K+
收藏 5

【Gopher China万字分享】华为云的Go语言云原生实战经验!>>>

Java 程序在使用 Socks5 代理访问国外网页的时候,经常会碰到同一个网页在浏览器上通过代理可以正常访问。但是在 Java 程序中通过同一个代理却无法访问的情况。

经过数个小时的研究发现这种情况只出现在个别网页,例如 twitter\facebook\reuters 等,于是大胆假设这个问题跟 DNS 的解析有关,然后通过搜索求证此假设,找到了 JDK 中存在的这样一个不足:

https://bugs.openjdk.java.net/browse/JDK-8028776

简单的概述就是 Java 只能通过本机来解析域名对应的 IP,而不能像浏览器一样可以设置通过代理来解析域名。而这个问题被 JDK 的团队认为优先级不高,目前还没有解决。

确定这个问题很简单,例如 reuters(路透社)的网站,我们可以通过 whois 找到其对应的 IP 地址,然后在 /etc/hosts 中映射其域名到对应的 IP 地址。再次运行程序即可正常访问。

测试代码很简单:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

/**
 * 测试使用 Socks 代理访问网页
 */
public class Socks5Tester {

	static int TIMEOUT = 1000 * 10;

	public static void main(String[] args) throws IOException {
		String url = "http://www.reuters.com/article/us-virtualreality-companies-stocks-idUSKCN0Y824Q";
		//String url = "https://git.oschina.net/";
		Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 1096)); 
		//System.out.print("Connecting to " + url );
		Document doc = Jsoup.connect(url)
				.proxy(proxy)
				.timeout(TIMEOUT)
				.validateTLSCertificates(false).get();
		System.out.println(doc.title());
		System.exit(0);
	}

}

那么该如何解决这个已经确认的问题呢?


加载中
2
红薯
红薯
据说可以通过下面这种方法来解决:
Proxy p = new Proxy(Proxy.Type.SOCKS, paddr);
Socket s = new Socket(p);
InetSocketAddress addr = InetSocketAddress.createUnresolved("host.blocked.by.gfw", port);
s.connect(addr);
返回顶部
顶部