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