private Socket createSocks4ProxySocket ( final String host , final int port ) { Socket socket = null ; final String proxyHost = proxy . getProxyAddress ( ) ; final int proxyPort = proxy . getProxyPort ( ) ; final String user = proxy . getProxyUsername ( ) ; try { socket = Sockets . connect ( proxyHost , proxyPort , connectionTimeout ) ; final InputStream in = socket . getInputStream ( ) ; final OutputStream out = socket . getOutputStream ( ) ; socket . setTcpNoDelay ( true ) ; byte [ ] buf = new byte [ 1024 ] ; // 1) CONNECT int index = 0 ; buf [ index ++ ] = 4 ; buf [ index ++ ] = 1 ; buf [ index ++ ] = ( byte ) ( port >>> 8 ) ; buf [ index ++ ] = ( byte ) ( port & 0xff ) ; InetAddress addr = InetAddress . getByName ( host ) ; byte [ ] byteAddress = addr . getAddress ( ) ; for ( byte byteAddres : byteAddress ) { buf [ index ++ ] = byteAddres ; } if ( user != null ) { System . arraycopy ( user . getBytes ( ) , 0 , buf , index , user . length ( ) ) ; index += user . length ( ) ; } buf [ index ++ ] = 0 ; out . write ( buf , 0 , index ) ; // 2) RESPONSE int len = 6 ; int s = 0 ; while ( s < len ) { int i = in . read ( buf , s , len - s ) ; if ( i <= 0 ) { throw new HttpException ( ProxyInfo . ProxyType . SOCKS4 , "stream is closed" ) ; } s += i ; } if ( buf [ 0 ] != 0 ) { throw new HttpException ( ProxyInfo . ProxyType . SOCKS4 , "proxy returned VN " + buf [ 0 ] ) ; } if ( buf [ 1 ] != 90 ) { try { socket . close ( ) ; } catch ( Exception ignore ) { } throw new HttpException ( ProxyInfo . ProxyType . SOCKS4 , "proxy returned CD " + buf [ 1 ] ) ; } byte [ ] temp = new byte [ 2 ] ; in . read ( temp , 0 , 2 ) ; return socket ; } catch ( RuntimeException rtex ) { closeSocket ( socket ) ; throw rtex ; } catch ( Exception ex ) { closeSocket ( socket ) ; throw new HttpException ( ProxyInfo . ProxyType . SOCKS4 , ex . toString ( ) , ex ) ; } }
Connects to the SOCKS4 proxy and returns proxified socket .