Java网络编程:实现客户端循环请求与多客户端压测求助
问题说明
我的客户端目前仅能向服务器发送单次请求,希望实现单个客户端循环发送20次请求,同时运行5个客户端生成负载,尝试实现但未成功,因不熟悉Java网络编程,寻求相关改进建议。
现有服务端代码
import java.io.*; import java.net.*; import java.util.ArrayList; import java.util.Random; public class MyServer { public static void main(String[] args) throws IOException { String jokes[] = {"j1", "j2", "j3"}; ServerSocket socket = new ServerSocket(9000); while(true){ Socket s = socket.accept(); PrintWriter print = new PrintWriter(s.getOutputStream(), true); String ip = (InetAddress.getLocalHost().getHostAddress()); print.println(ip+jokes[(int)(Math.random()*(jokes.length-1))]); s.close(); print.close(); } } }
现有客户端代码
import java.io.*; import java.net.*; public class MyClient{ public static void main(String[]args) throws IOException{ System.out.println(args[0]); System.out.println(args[1]); Socket socket = new Socket(args[0], Integer.parseInt(args[1])); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); String message; while((message = in.readLine()) != null) { System.out.println(message); System.out.println(cnt); } socket.close(); } }
改进方案
1. 服务端:改为多线程处理连接
当前服务端是单线程模式,同一时间只能处理一个客户端请求,会阻塞后续连接,无法模拟真实负载。修改为多线程处理,每个客户端连接单独用线程处理:
import java.io.*; import java.net.*; public class MyServer { private static final String[] JOKES = {"j1", "j2", "j3"}; public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(9000); System.out.println("服务器启动,监听端口9000..."); while (true) { Socket clientSocket = serverSocket.accept(); // 启动新线程处理当前客户端请求 new Thread(() -> handleClient(clientSocket)).start(); } } private static void handleClient(Socket clientSocket) { try (PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); Socket socket = clientSocket) { // 自动关闭资源,避免泄漏 String ip = InetAddress.getLocalHost().getHostAddress(); // 修复随机数范围:原代码无法取到最后一个笑话j3 String joke = JOKES[(int) (Math.random() * JOKES.length)]; out.println(ip + joke); } catch (IOException e) { e.printStackTrace(); } } }
2. 客户端:实现循环20次请求
当前客户端仅建立一次连接,需添加循环逻辑,同时修复cnt未定义的问题:
import java.io.*; import java.net.*; public class MyClient { public static void main(String[] args) throws IOException { if (args.length != 2) { System.out.println("用法: java MyClient <服务器IP> <端口>"); return; } String serverIp = args[0]; int port = Integer.parseInt(args[1]); final int REQUEST_TIMES = 20; for (int cnt = 1; cnt <= REQUEST_TIMES; cnt++) { // 每次循环新建连接(服务端处理完即关闭连接) try (Socket socket = new Socket(serverIp, port); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) { String message = in.readLine(); if (message != null) { System.out.println("第" + cnt + "次请求响应: " + message); } } catch (IOException e) { System.out.println("第" + cnt + "次请求失败: " + e.getMessage()); } // 可选:添加100ms延迟,模拟真实请求间隔 try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } System.out.println("20次请求完成"); } }
3. 启动5个客户端生成负载
- 手动方式:打开5个终端窗口,每个窗口执行命令:
java MyClient 127.0.0.1 9000 - 脚本方式(Linux/macOS):用shell脚本批量启动后台进程
for i in {1..5}; do java MyClient 127.0.0.1 9000 & done
额外建议
- 服务端可添加日志记录,方便排查连接和请求问题
- 客户端可添加连接超时设置,避免无响应等待:
Socket socket = new Socket(); socket.connect(new InetSocketAddress(serverIp, port), 3000); // 设置3秒超时 - 若需要更高并发,可考虑使用线程池管理客户端请求,或改用HTTP协议搭配Apache HttpClient等工具库
内容的提问来源于stack exchange,提问作者Osca
相关产品推荐
相关产品推荐

