如何在Java中使用SOCKS?
我使用 100% 正常工作的 SOCKS,但无法通过我的应用程序进行连接:
SocketAddress proxyAddr = new InetSocketAddress("1.1.1.1", 12345);
Proxy pr = new Proxy(Proxy.Type.SOCKS, proxyAddr);
try {
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection(pr);
con.setConnectTimeout(proxyTimeout * 1000);
con.setReadTimeout(proxyTimeout * 1000);
con.connect();
System.out.println(con.usingProxy());
} catch (IOException ex) {
Logger.getLogger(Enter.class.getName()).log(Level.SEVERE, null, ex);
}
那么我做错了什么?如果我将 HTTP 与某些 HTTP 代理一起使用,那么一切都可以正常工作,但与 SOCKS 则不行。
I use 100% working SOCKS and I can't connect through my application:
SocketAddress proxyAddr = new InetSocketAddress("1.1.1.1", 12345);
Proxy pr = new Proxy(Proxy.Type.SOCKS, proxyAddr);
try {
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection(pr);
con.setConnectTimeout(proxyTimeout * 1000);
con.setReadTimeout(proxyTimeout * 1000);
con.connect();
System.out.println(con.usingProxy());
} catch (IOException ex) {
Logger.getLogger(Enter.class.getName()).log(Level.SEVERE, null, ex);
}
So what am I doing wrong? If I use HTTP with some HTTP proxy all is working, but not with SOCKS.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
或者这个答案: https://stackoverflow.com/a/64649010/5352325
如果您知道需要转到哪些 URI代理,您还可以使用低层ProxySelector: https ://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html 对于建立的每个 Socket 连接,您可以决定使用哪些代理。
它看起来像这样:
然后你使用你的选择器:
Or this answer: https://stackoverflow.com/a/64649010/5352325
If you know which URIs need to go to proxy, you can also use the low layer ProxySelector: https://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html where for each Socket connection that is made, you can decide what proxies are to be used.
It looks something like this:
Then you make use of your selector:
全局代理
您可以传递 JVM 参数来设置将应用于所有 JVM 网络流量的 SOCKS 代理:
更灵活的方法是在运行时使用系统属性来设置它:
当您需要时,最好使用通过 JVM 参数或系统属性设置代理需要确保整个应用程序都使用代理。例如,当您需要代理 Spring Boot 应用程序以连接到数据库或类似的东西时。
每个连接代理
这是设置代理的最灵活的方法,因为您可以基于每个连接进行设置。以下是使用 Java 11
HttpClient
和旧版HttpURLConnection
进行按连接代理的示例:当您想要隔离对特定请求的代理或动态切换时,此方法最有用运行时代理。您还可以将全局代理与按请求代理混合使用,这样您就可以设置全局代理,但通过不同的代理发送特定请求。
您可以在此处阅读有关 Java 代理的更多信息:https:// /docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html
Global Proxy
You can pass JVM arguments to setup a SOCKS proxy that will be applied to all JVM network traffic:
A more flexible approach is to set it using system properties during runtime:
Setting the proxy via JVM arguments or system properties is best used when you need to ensure the entire application is using a proxy. For example, when you need to proxy a Spring Boot application to connect to a database or something like that.
Per-Connection Proxy
This is the most flexible way of setting up proxies, as you can set it on a per-connection basis. Here is an example of per-connection proxying with the Java 11
HttpClient
and the legacyHttpURLConnection
:This approach is most useful when you want to isolate proxying to specific requests or dynamically switch proxies during runtime. You can also mix global proxying with per-request proxying, so you can set a global proxy, but send specific requests trough a different proxy.
You can read more on Java proxying here: https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html
这真的很容易。您只需要设置相关的系统属性并继续使用常规的 HttpConnection 即可。
It's really easy. You just need to set the relevant System Properties and just get on with your regular HttpConnection.
通知“socksProxyHost”和“socksProxyPort”VM 参数。
例如
Inform the "socksProxyHost" and "socksProxyPort" VM arguments.
e.g.
http://grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/sun/net/www/http/HttpClient.java/?v=源码
深层来说,HttpClient是在HttpURLConnection中使用的。
在第 476 行,您可以看到唯一可接受的代理是 HTTP 代理。否则它会建立直接连接。
奇怪的是,不支持使用 HttpURLConnection 的 SOCKS 代理。更糟糕的是,代码甚至不使用不受支持的代理,而只是忽略代理!
无法解释为什么在此类存在至少 10 年之后没有对 SOCKS 代理提供任何支持。
http://grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/sun/net/www/http/HttpClient.java/?v=source
Deep down, HttpClient is used in HttpURLConnection.
On line 476, you can see that the only acceptable proxy is an HTTP proxy. It makes a direct connection otherwise.
Weirdly there's is no support for SOCKS proxy using HttpURLConnection. Even worse, the code doesn't even t using an unsupported proxy and just ignores the proxy!
Why there isn't any support for SOCKS proxies after at least 10 years of this class' existence cannot be explained.