MST

星途 面试题库

面试题:Java中Socket编程代理模式的基础实现

请用Java代码实现一个简单的Socket编程中代理模式的示例,要求包含代理类、被代理类以及客户端调用代码,并简要解释代理模式在Socket编程中的作用。
24.6万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

1. 被代理类(真实服务器)

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class RealServer {
    private int port;

    public RealServer(int port) {
        this.port = port;
    }

    public void handleRequest() {
        try (ServerSocket serverSocket = new ServerSocket(port);
             Socket clientSocket = serverSocket.accept();
             Scanner in = new Scanner(clientSocket.getInputStream());
             PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true)) {
            System.out.println("Real server connected by " + clientSocket.getInetAddress());
            String inputLine;
            while ((inputLine = in.nextLine()) != null) {
                System.out.println("Real server received: " + inputLine);
                out.println("Real server response: " + inputLine);
                if ("exit".equals(inputLine)) {
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2. 代理类

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class ProxyServer {
    private String realServerHost;
    private int realServerPort;

    public ProxyServer(String realServerHost, int realServerPort) {
        this.realServerHost = realServerHost;
        this.realServerPort = realServerPort;
    }

    public void handleRequest(Socket clientSocket) {
        try (Scanner clientIn = new Scanner(clientSocket.getInputStream());
             PrintWriter clientOut = new PrintWriter(clientSocket.getOutputStream(), true);
             Socket realServerSocket = new Socket(realServerHost, realServerPort);
             Scanner serverIn = new Scanner(realServerSocket.getInputStream());
             PrintWriter serverOut = new PrintWriter(realServerSocket.getOutputStream(), true)) {
            System.out.println("Proxy server connected by " + clientSocket.getInetAddress());
            String inputLine;
            while ((inputLine = clientIn.nextLine()) != null) {
                System.out.println("Proxy server received from client: " + inputLine);
                serverOut.println(inputLine);
                String serverResponse = serverIn.nextLine();
                System.out.println("Proxy server received from real server: " + serverResponse);
                clientOut.println(serverResponse);
                if ("exit".equals(inputLine)) {
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3. 客户端调用代码

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) {
        String proxyServerHost = "localhost";
        int proxyServerPort = 8888;
        try (Socket socket = new Socket(proxyServerHost, proxyServerPort);
             Scanner in = new Scanner(socket.getInputStream());
             PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
             Scanner stdIn = new Scanner(System.in)) {
            System.out.println("Connected to proxy server.");
            String userInput;
            while ((userInput = stdIn.nextLine()) != null) {
                out.println(userInput);
                System.out.println("Client received: " + in.nextLine());
                if ("exit".equals(userInput)) {
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

代理模式在Socket编程中的作用

  • 隐藏真实服务器细节:客户端无需知道真实服务器的具体位置和实现细节,只需要与代理服务器交互,降低了客户端与真实服务器之间的耦合度。
  • 增强功能:代理服务器可以在转发请求和响应的过程中,添加额外的功能,比如日志记录、缓存、身份验证、流量控制等。例如,代理服务器可以记录每个客户端的请求信息,便于后续分析和维护。
  • 负载均衡:通过代理服务器,可以将客户端的请求均匀地分配到多个真实服务器上,提高系统的整体性能和可用性。例如,在高并发场景下,代理服务器可以根据各个真实服务器的负载情况,动态地选择响应请求的服务器。