You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 07:11:05