如何为 SOCKS 代理设置 nonProxyHosts?

Posted

技术标签:

【中文标题】如何为 SOCKS 代理设置 nonProxyHosts?【英文标题】:How to set nonProxyHosts for a SOCKS proxy? 【发布时间】:2014-10-16 05:46:10 【问题描述】:

我想为 SOCKS5 代理设置nonProxyHosts 列表,即应该使用直接连接的主机名列表。

正如oracle docs 所描述的,有名为http.nonProxyHostsftp.nonProxyHosts 的选项可以为HTTP 和FTP 设置代理排除项,但没有针对SOCKS 代理的特定设置。

我试过http.nonProxyHosts,但这不会影响 SOCKS 连接。

SOCKS 代理通过以下方式设置:

System.setProperty("socksProxyHost", "192.168.10.10");
System.setProperty("socksProxyPort", "3128");

但这会导致即使是与localhost 的数据库连接也正在使用 SOCKS 代理,这是不可接受的。 这个应该怎么用?如何从代理连接中排除某些主机?

【问题讨论】:

我需要相同的功能。恐怕目前还没有实现 SOCKS 的 nonProxyHosts。 【参考方案1】:

使用socksNonProxyHosts系统属性;这是未记录的,但存在于 Oracle JDK 8 到 11 中,可能还有其他版本。

java -DsocksProxyHost=mySocksServer -DsocksProxyPort=8888 -DsocksNonProxyHosts=127.0.0.1 [...]

TL;DR

socksNonProxyHosts 的属性可以在 sun.net.spi.DefaultProxySelector 的源代码中找到(感谢 @rince)

但是,Java 网络属性的 documentation 暗示这不存在,因此它的使用可能不稳定:

一旦以这种方式指定了 SOCKS 代理,所有 TCP 连接将通过该代理进行尝试。

(已添加重点)

您也许可以使用Proxy 和/或ProxySelector 类,但是:

ProxySelector 仅适用于您的应用程序使用URLConnection 建立连接的情况。

Proxy 适用于任意套接字...但前提是您可以将 Proxy 对象作为参数提供给相关的 Socket 构造函数调用。 (并且您需要逻辑来提供不同的 Proxy 对象,具体取决于您的代码尝试连接的对象。)

有一个bug for this RFE for this。该票提出了另一种解决方法。显然,如果java.net.useSystemProxies 属性是true,那么(在某些平台上)默认代理选择器将尊重在相应系统代理设置中指定的排除主机。

【讨论】:

对于其他阅读本文的人来说,看起来该错误已针对 Java 8(b86) 进行了修复。 @xdhmoore 你能告诉我一些关于这个错误修复的文档吗? @Tucker 这是上面链接的那个。 这个bug没有命名实际的属性,你必须去寻找DefaultProxySelector的源代码。属性是 socksNonProxyHosts 确实,截至 Java 9 版本,他们还没有在 docs.oracle.com/javase/9/docs/api/java/net/doc-files/… 中记录此属性

以上是关于如何为 SOCKS 代理设置 nonProxyHosts?的主要内容,如果未能解决你的问题,请参考以下文章

如何为chrome浏览器设置socks5代理

求教如何为Java NIO设置Socks代理

如何为 Git 设置代理

在windows下如何为特定进程设置指定代理?

如何为linux系统设置全局的默认网络代理

JavaMail:如何为不同的线程使用不同的 SOCKS5?