如何在android app中使用socks5代理?

时间:2018-01-31 10:12:58

标签: android proxy socks

目的是在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。谁能告诉我我做错了什么?

0 个答案:

没有答案