目的是在android app中使用socks5进行所有连接。正如它在这里所说https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html, 我只需要使用系统属性来设置port,hostname和socks版本:
System.setProperty("socksProxyHost",addr);
System.setProperty("socksProxyPort",port);
System.setProperty("socksProxyVersion","5")
然后创建一个连接:
protected String doInBackground(String... sUrl) {
OutputStream output = null;
InputStream input = null;
byte data[] = new byte[4096];
int total = 0, fileNameLength = sUrl[0].length();
int count;
try {
// Download file from URL
URL url = new URL(sUrl[0]);
SocketAddress socketAddress;
connection = (HttpsURLConnection)url.openConnection();
//Accepting all certs
TrustManager[] trustManagers = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) { }
public void checkServerTrusted(X509Certificate[] certs, String authType) { }
}
};
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return s.equals(sslSession.getPeerHost());
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagers, null);
connection.setSSLSocketFactory(sslContext.getSocketFactory());
connection.setHostnameVerifier(hostnameVerifier);
input = connection.getInputStream();
但是当我嗅探流量时,它总是使用socks4。 Http,Https代理按预期工作。然后我试着找出哪种类型的套接字创建,如果我调用Socket构造函数直接指定代理:
Socket socket = new Socket(new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(proxyAddr, proxyPort)));
Class clazzSocks = socket.getClass();
Method setSockVersion = null;
Field sockImplField = null;
SocketImpl socksimpl = null;
sockImplField = clazzSocks.getDeclaredField("impl");
sockImplField.setAccessible(true);
socksimpl = (SocketImpl) sockImplField.get(socket);
Class clazzSocksImpl = socksimpl.getClass();
它表明clazzSocksImpl是PlainSocketImpl而不是我期望的SocksSocketImpl。谁能告诉我我做错了什么?