Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何通过HTTP代理连接套接字服务器_Java_Sockets_Httpclient - Fatal编程技术网

Java 如何通过HTTP代理连接套接字服务器

Java 如何通过HTTP代理连接套接字服务器,java,sockets,httpclient,Java,Sockets,Httpclient,我有一段连接到套接字服务器的代码,它可以正常工作 Socket socket = new Socket(); socket.connect(new InetSocketAddress(address, port)); 现在我想通过HTTP代理进行连接,我应该怎么做 我试过了,但失败了 SocketAddress proxyAddr = new InetSocketAddress(proxyHost, proxyPort); Proxy proxy = new Proxy(Proxy.Type.

我有一段连接到套接字服务器的代码,它可以正常工作

Socket socket = new Socket();
socket.connect(new InetSocketAddress(address, port));
现在我想通过HTTP代理进行连接,我应该怎么做

我试过了,但失败了

SocketAddress proxyAddr = new InetSocketAddress(proxyHost, proxyPort);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, addr);
Socket socket = new Socket(proxy);
socket.connect(new InetSocketAddress(address, port));
建议我应该使用Jakarta Commons HttpClient,但是如何使用它通过HTTP代理连接套接字服务器呢

更新: 我使用了SOCKS代理,但它不起作用,如果我使用HTTP代理:

SocketAddress proxyAddr = new InetSocketAddress(proxyHost, proxyPort);
Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);
Socket socket = new Socket(proxy);
socket.connect(new InetSocketAddress(address, port));
它将抛出一个非法的辩论例外

java.lang.IllegalArgumentException: Proxy is null or invalid type
    at java.net.Socket.<init>(Socket.java:88)
java.lang.IllegalArgumentException:代理为null或无效类型
位于java.net.Socket(Socket.java:88)

看起来您正在请求SOCKS代理,这与HTTP代理不同。也许可以尝试Proxy.Type.HTTP

问题:您的客户端是基于HTTP的吗?除非您的客户端使用HTTP,否则我不确定这是否有效。

您可以尝试,尽管您需要在隧道两侧运行软件才能正常工作。

根据Wikipedia on,HTTP代理的重要一点是它代理HTTP协议

因此,如果您有一个服务器和一个客户机,并且希望它们通过HTTP代理进行通信,那么必须修改服务器和客户机,以使用HTTP协议进行通信

或者,您还需要其他软件来实现,例如OpenVPN


Edit:例外情况是,一些HTTP代理服务器支持并启用了一个方法,在HTTP上执行基本设置过程后,该方法允许创建和路由常规TCP套接字。这允许连接到应用程序,而无需进行完全转换为HTTP隧道的艰苦工作。MSN Messenger就是一个很好的例子。然而,正如维基百科文章所指出的,由于安全原因,该功能经常被禁用,甚至不受支持。

这是我之前发布的链接:

SocketAddress addr = new InetSocketAddress("webcache.mydomain.com", 8080);
Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);
记住,这个新的代理对象仅代表一个代理定义。我们如何使用这样的对象?URL类中添加了一个新的
openConnection()
方法,该方法将代理作为参数,其工作方式与
openConnection()
相同,没有参数,只是它强制通过指定的代理建立连接,忽略所有其他设置,包括上述系统属性

完成前面的示例后,我们现在可以添加:

URL url = new URL("http://java.sun.com/");
URLConnection conn = url.openConnection(proxy);

这是我之前发布的链接。我在iPad上,所以无法正确格式化


你能这样做吗?我看到您直接在做套接字,但您在做http,所以可能是这样做的?

我说的您想要的是使用http代理(例如squid)建立到远程服务器的连接方法(从http rfc 2616)是正确的吗?基本上,连接是这样的:

     -open a socket to the proxy (host, port)
     -send text to the proxy with basic header 
     ....CONNECT remote.internethost.com:1494 HTTP/1.0
     ....User-Agent: Java Proxy Socket version 1.0a
     ....Host: remote.internethost.com
     ....Proxy-Authorization: Basic YourBase64usernamePasswordIfRequired
     -then, the proxy will return a http status code (multiline text string) and the actual socket (if successfull)
     -this is this socket that needs to be returned to the connection object

这可以通过个人类来实现,但好处是可以重用代理类。这样,所有与http代理的握手,尤其是响应代码都将得到处理。

好的,您可以通过在代理的url之后设置请求的url,或使用Java url来管理代理,如下所示:

URL u = new URL("http", ProxyHost, ProxyPort, destinationAddress);
通过使用它,您可以构建一个类似
http://ProxyHost:ProxyPorthttp://destinationAddress
因此,您不必在Java中设置可能引发上述异常的代理类实例:

java.lang.IllegalArgumentException: Proxy is null or invalid type
    at java.net.Socket.<init>(Socket.java:88)

尽管这是设置代理的一种非常“基本”的方法,但如果您必须设置HTTP类型的代理,那么它很可能适用于HTTP类型的代理。

我创建了一个小型套接字工厂类来处理通过套接字的HTTP连接。然后,只要代理支持连接到目标,就可以按照正常方式使用套接字

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);
        }
    }
}
公共最终类SocketFactory{
公共静态套接字GetSocket(字符串主机、字符串端口)引发IOException{
/*************************
*获取jvm参数
*************************/
int-proxyPort=Integer.parseInt(System.getProperty(“http.proxyPort”));
字符串proxyHost=System.getProperty(“http.proxyHost”);
//连接到代理的套接字对象
Socket sock=新套接字(代理主机、代理端口);
/***********************************
*HTTP连接协议RFC2616
***********************************/
字符串proxyConnect=“CONNECT”+主机+:“+端口;
//如果设置了proxyUser和proxyPass,则添加代理授权
试一试{
String proxyUserPass=String.format(“%s:%s”,
System.getProperty(“http.proxyUser”),
System.getProperty(“http.proxyPass”);
concat(“HTTP/1.0\n代理授权:基本”
+Base64.encode(proxyUserPass.getBytes());
}捕获(例外e){
}最后{
proxyConnect.concat(“\n\n”);
}
sock.getOutputStream().write(proxyConnect.getBytes());
/***********************************/
/***************************
*验证HTTP响应。
***************************/
字节[]tmpBuffer=新字节[512];
InputStream socketInput=sock.getInputStream();
int len=socketInput.read(tmpBuffer,0,tmpBuffer.length);
如果(len==0){
抛出新的SocketException(“来自代理的无效响应”);
}
字符串代理响应=新字符串(tmpBuffer,0,len,“UTF-8”);
//应该是HTTP/1.x200,可以吗
if(proxyResponse.indexOf(“200”)!=-1){
//刷新缓冲区中任何未完成的消息
if(socketInput.available()>0)
socketInput.skip(socketInput.available());
//代理连接成功,返回IO的套接字
返回袜子;
}否则{
抛出新的SocketFactoryException(“无法创建套接字”,
促氧化反应);
}
}
/**
*采用GeorgeK最简单的Base64编码器
* 
*@见http://stackoverflow.com/questions/469695/decode-base64-data-in-java/4265472#42654
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);
        }
    }
}
Socket socketProxy = null;
    if(System.getProperty("http.proxyHost") != null) {
        if(System.getProperty("http.proxyUser") != null) {
            
            String proxyUser = System.getProperty("http.proxyUser");
            String proxyPassword = System.getProperty("http.proxyPassword");
            
            //For Proxy Authentication
            Authenticator.setDefault( new Authenticator() {
            
             @Override public PasswordAuthentication getPasswordAuthentication() { return
             new PasswordAuthentication(proxyUser, proxyPassword.toCharArray()); } } ); 
             
             System.setProperty("jdk.http.auth.tunneling.disabledSchemes", ""); // By default basic auth is disabled, by this basic auth is enabled
        }
    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(System.getProperty("http.proxyHost"), Integer.parseInt(System.getProperty("http.proxyPort"))));
    socketProxy = new Socket(proxy);
    InetSocketAddress address = InetSocketAddress.createUnresolved(host, port); // create a socket without resolving the target host to IP
    socketProxy.connect(address); 
    }
SocketAddress **proxyAddr** = new InetSocketAddress(proxyHost, proxyPort);
Proxy proxy = new Proxy(Proxy.Type.HTTP, **addr**);
Socket socket = new Socket(proxy);
socket.connect(new InetSocketAddress(address, port));