📜  在Java设置到系统的代理连接

📅  最后修改于: 2022-05-13 01:54:51.043000             🧑  作者: Mango

在Java设置到系统的代理连接

在当今的网络环境中,绝对是企业环境中,应用程序开发人员实际上必须像系统管理员一样经常处理代理。在某些情况下,应用程序应该使用系统默认设置,在其他情况下,对通过哪个代理进行的内容进行非常严格的控制将是附加的,并且在中间的某个地方,大多数应用程序会欣喜若狂地将决定委派给他们为用户提供 GUI 来设置代理设置,就像大多数浏览器一样。

代理服务器充当客户端应用程序和其他服务器之间的接口。在企业环境中,我们经常使用它们来帮助控制用户消费的内容,通常是跨越网络边界。

方法:

我们将找出两种可以在Java跨代理服务器进行连接的方法,如下所示:



  1. 在 JVM 范围内使用系统属性配置的传统方法。
  2. 使用 Proxy 类,它通过允许基于每个连接的配置来提供更多控制。

方法 1:使用全局设置

Java展示了一组系统属性,可用于设置 JVM 范围的行为。如果适用于用例,这种“通用”方法通常是最容易实现的。我们可以在调用 JVM 期间从命令行设置所需的属性。或者,我们也可以在运行时使用 System.setProperty() 定义它们。以下是使用命令行定义它们的方法,如下所示:

2.1.通过命令行参数设置

我们可以在命令行中定义代理绕过参数作为系统属性:

当以这种方式启动一个进程时,我们可以在 URL 上使用openConnection()而不需要额外的工作:

2.3使用 System.setProperty() 方法设置代理

如果在使用命令行时出现问题,还有另一种方法可以使用 System.setProperty() 方法来执行此操作。设置代理。

如果我们随后手动禁用相关的系统属性,则将不再使用代理:

现在,这确实存在全局配置的限制,如下所述。



  • 全局配置方式是定义代理最简单的方式,但这种方式存在一定的局限性。
  • 这种方法提供了在 JVM 范围内的实现,因此为特定协议定义的设置在 JVM 的生命周期内都是有效的,或者直到我们手动取消设置它们。

注意:为了克服这个限制,如果需要,打开和关闭设置可能很有吸引力。但是,有必要确保采取措施防止多线程程序中的并发问题。

因此,作为替代方案,代理 API 更高效,并提供对代理配置的更多控制。作为替代方案,代理 API 提供对代理配置的更精细控制。这催生了另一种通过代理 API 的方法

方法二:使用代理API

Proxy 类为我们提供了一种灵活的方式来在每个连接的基础上配置代理。如果存在任何现有的 JVM 范围代理设置,则使用 Proxy 类的基于连接的代理设置将覆盖它们。以下是我们可以通过 Proxy Type 定义的三种类型的代理:

  1. HTTP是使用 HTTP 协议的代理
  2. SOCKS是使用 SOCKS 协议的代理
  3. DIRECT是一个显式配置的直接连接,没有代理

(A)使用 HTTP 代理

要使用 HTTP 代理,我们首先使用 Proxy 和 Proxy.Type.HTTP 类型包装一个 SocketAddress 实例。接下来,我们只需将 Proxy 实例传递给 URLConnection.openConnection():

现在,我们将连接到 URL_STRING,然后通过托管在 127.0.0.1:8080 的代理服务器路由该连接。



(B)使用直接代理

我们可能需要直接连接到主机。在这种情况下,我们可以使用静态 Proxy.NO_PROXY 实例显式绕过可以全局配置的代理。在幕后,API 为我们构造了一个新的 Proxy 实例,使用 Proxy.Type.DIRECT 作为类型:

(C)使用 SOCKS 代理

在处理 URLConnection 时,Socks 代理的工作方式与 HTTP 变体类似。在 Socks 代理中,首先,我们使用 Proxy.Type.SOCKS 类型用代理包装一个 SocketAddress 实例。之后,将 Proxy 实例传递给 URLConnection.openConnection。

连接到 TCP 套接字时也可以使用 SOCKS 代理。首先,我们使用 Proxy 实例来构造一个 Socket。之后,我们将目标 SocketAddress 实例传递给 Socket.connect() ,如下所示:

例子:

Java
// Java Program to Create a Simple Proxy Server
  
// Importing input output classes
import java.io.*;
// Importing
import java.net.*;
  
public class SimpleProxyServer {
    public static void main(String[] args)
        throws IOException
    {
        try {
            String host = "your Proxy Server";
            int remoteport = 100;
            int localport = 111;
            // Print a start-up message
            System.out.println("Starting proxy for " + host
                               + ":" + remoteport
                               + " on port " + localport);
            // And start running the server
            runServer(host, remoteport,
                      localport); // never returns
        }
        catch (Exception e) {
            System.err.println(e);
        }
    }
  
    /**
     * runs a single-threaded proxy server on
     * the specified local port. It never returns.
     */
    public static void
    runServer(String host, int remoteport, int localport)
        throws IOException
    {
        // Create a ServerSocket to listen for connections
        // with
        ServerSocket ss = new ServerSocket(localport);
  
        final byte[] request = new byte[1024];
        byte[] reply = new byte[4096];
  
        while (true) {
            Socket client = null, server = null;
            try {
                // Wait for a connection on the local port
                client = ss.accept();
  
                final InputStream streamFromClient
                    = client.getInputStream();
                final OutputStream streamToClient
                    = client.getOutputStream();
  
                // Make a connection to the real server.
                // If we cannot connect to the server, send
                // an error to the client, disconnect, and
                // continue waiting for connections.
                try {
                    server = new Socket(host, remoteport);
                }
                catch (IOException e) {
                    PrintWriter out
                        = new PrintWriter(streamToClient);
                    out.print(
                        "Proxy server cannot connect to "
                        + host + ":" + remoteport + ":\n"
                        + e + "\n");
                    out.flush();
                    client.close();
                    continue;
                }
  
                // Get server streams.
                final InputStream streamFromServer
                    = server.getInputStream();
                final OutputStream streamToServer
                    = server.getOutputStream();
  
                // a thread to read the client's requests
                // and pass them to the server. A separate
                // thread for asynchronous.
                Thread t = new Thread() {
                    public void run()
                    {
                        int bytesRead;
                        try {
                            while ((bytesRead
                                    = streamFromClient.read(
                                        request))
                                   != -1) {
                                streamToServer.write(
                                    request, 0, bytesRead);
                                streamToServer.flush();
                            }
                        }
                        catch (IOException e) {
                        }
  
                        // the client closed the connection
                        // to us, so close our connection to
                        // the server.
                        try {
                            streamToServer.close();
                        }
                        catch (IOException e) {
                        }
                    }
                };
  
                // Start the client-to-server request thread
                // running
                t.start();
  
                // Read the server's responses
                // and pass them back to the client.
                int bytesRead;
                try {
                    while ((bytesRead
                            = streamFromServer.read(reply))
                           != -1) {
                        streamToClient.write(reply, 0,
                                             bytesRead);
                        streamToClient.flush();
                    }
                }
                catch (IOException e) {
                }
  
                // The server closed its connection to us,
                // so we close our connection to our client.
                streamToClient.close();
            }
            catch (IOException e) {
                System.err.println(e);
            }
            finally {
                try {
                    if (server != null)
                        server.close();
                    if (client != null)
                        client.close();
                }
                catch (IOException e) {
                }
            }
        }
    }
}


输出:

结论:根据输出,我们了解了如何在核心Java使用代理服务器。首先,我们研究了使用系统属性通过代理服务器进行连接的较旧的、更具全局性的方式。然后,我们看到了如何使用 Proxy 类,它在通过代理服务器连接时提供细粒度的控制。