How to connect a Socket server via HTTP proxy

后端 未结 8 1184
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-02-02 14:08

I have a piece of code to connect to a Socket server, and it works fine.

Socket socket = new Socket();
socket.connect(new InetSocketAddress(address, port));
         


        
8条回答
  •  花落未央
    2021-02-02 14:40

    I've created small Socket Factory class to handle the HTTP CONNECT via socket. The socket then can be used as per-normal provided the proxy supports CONNECT to the destination.

    public final class SocketFactory {
    
        public static Socket GetSocket(String host, String port) throws IOException {
    
            /*************************
             * Get the jvm arguments
             *************************/
    
            int proxyPort = Integer.parseInt(System.getProperty("http.proxyPort"));
            String proxyHost = System.getProperty("http.proxyHost");
    
            // Socket object connecting to proxy
            Socket sock = new Socket(proxyHost, proxyPort);
    
            /***********************************
             * HTTP CONNECT protocol RFC 2616
             ***********************************/
            String proxyConnect = "CONNECT " + host + ":" + port;
    
            // Add Proxy Authorization if proxyUser and proxyPass is set
            try {
                String proxyUserPass = String.format("%s:%s",
                        System.getProperty("http.proxyUser"),
                        System.getProperty("http.proxyPass"));
    
                proxyConnect.concat(" HTTP/1.0\nProxy-Authorization:Basic "
                        + Base64.encode(proxyUserPass.getBytes()));
            } catch (Exception e) {
            } finally {
                proxyConnect.concat("\n\n");
            }
    
            sock.getOutputStream().write(proxyConnect.getBytes());
            /***********************************/
    
            /***************************
             * validate HTTP response.
             ***************************/
            byte[] tmpBuffer = new byte[512];
            InputStream socketInput = sock.getInputStream();
    
            int len = socketInput.read(tmpBuffer, 0, tmpBuffer.length);
    
            if (len == 0) {
                throw new SocketException("Invalid response from proxy");
            }
    
            String proxyResponse = new String(tmpBuffer, 0, len, "UTF-8");
    
            // Expecting HTTP/1.x 200 OK
            if (proxyResponse.indexOf("200") != -1) {
    
                // Flush any outstanding message in buffer
                if (socketInput.available() > 0)
                    socketInput.skip(socketInput.available());
    
                // Proxy Connect Successful, return the socket for IO
                return sock;
            } else {
                throw new SocketFactoryException("Fail to create Socket",
                        proxyResponse);
            }
        }
    
        /**
         * Simplest Base64 Encoder adopted from GeorgeK
         * 
         * @see http://stackoverflow.com/questions/469695/decode-base64-data-in-java/4265472#4265472
         */
        private static class Base64 {
            /***********************
             * Base64 character set
             ***********************/
            private final static char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
                    .toCharArray();
    
            /**
             * Translates the specified byte array into Base64 string.
             * 
             * @param buf
             *            the byte array (not null)
             * @return the translated Base64 string (not null)
             */
            public static String encode(byte[] buf) {
                int size = buf.length;
                char[] ar = new char[((size + 2) / 3) * 4];
                int a = 0;
                int i = 0;
                while (i < size) {
                    byte b0 = buf[i++];
                    byte b1 = (i < size) ? buf[i++] : 0;
                    byte b2 = (i < size) ? buf[i++] : 0;
    
                    int mask = 0x3F;
                    ar[a++] = ALPHABET[(b0 >> 2) & mask];
                    ar[a++] = ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask];
                    ar[a++] = ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask];
                    ar[a++] = ALPHABET[b2 & mask];
                }
                switch (size % 3) {
                case 1:
                    ar[--a] = '=';
                case 2:
                    ar[--a] = '=';
                }
                return new String(ar);
            }
        }
    }
    

    https://code.google.com/p/java-socket-over-http-proxy-connect/

提交回复
热议问题