jmeter自定义TcpClient,实现自定义TCP取样器的读写规则

jmeter的TCPClient classname,可以使用自定义的java代码替代,这样就可以实现发送部分特定格式的二进制数据,并且返回的数据也可以自行编写解析的方法。并且,不需要再关注行尾(EOL)字节值。
假设需要发送和接收的二进制数据,格式如下:int(报文长度),int(报文ID),string(报文内容)。
编写代码如下:

import org.apache.jmeter.protocol.tcp.sampler.AbstractTCPClient;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

//主要任务是 重写 AbstractTCPClient的函数
public class LengthPrefixedTcpClient extends AbstractTCPClient {
    //String s就是tcp取样器的“要发送的文本”的内容
    @Override
    public void write(OutputStream os, String s) throws IOException {
        //报文内容
        byte[] payload = s.getBytes("UTF-8");
        //报文长度
        int msgLength = 4 + payload.length;
        //报文ID
        int msgId = 100;

        //报文将报文长度 + 报文ID + 报文内容存入
        ByteBuffer buffer = ByteBuffer.allocate(4 + 4 + payload.length);
        buffer.putInt(msgLength);
        buffer.putInt(msgId);
        buffer.put(payload);

        os.write(buffer.array());
        os.flush();
    }

    @Override
    public void write(OutputStream outputStream, InputStream inputStream) {
        throw new UnsupportedOperationException(
                "Method not supported for Length-Prefixed data.");
    }

    @Override
    public String read(InputStream is) {
        try {
            //依据类型的长度,解析报文
            byte[] lenBytes = new byte[4];
            is.read(lenBytes);
            int length = ByteBuffer.wrap(lenBytes).getInt();

            byte[] msgIdBytes = new byte[4];
            is.read(msgIdBytes);
            int msgId = ByteBuffer.wrap(msgIdBytes).getInt();

            int contentLength = length - 4;
            byte[] content = new byte[contentLength];
            is.read(content);

            //NOTE 返回值会在"查看结果树"的响应数据中显示
            return "msgId: " + msgId + ", body: " + new String(content, StandardCharsets.UTF_8);
        } catch (IOException e) {
            e.printStackTrace();
            return "read error: " + e.getMessage();
        }
    }
}

代码实现后,需要找到jmeter的ext\ApacheJMeter_tcp.jar(即AbstractTCPClient的依赖)的路径,再作为-cp参数传入编译命令中,例如:

javac -cp "D:\Applications\apache-jmeter-5.6.3\lib\ext\ApacheJMeter_tcp.jar" "C:\Users\p\Desktop\新建文件夹\jmetertcpclient\LengthPrefixedTcpClient.java"

编译后,生成.class文件。
再将.class文件打包成.jar:

jar cvf LengthPrefixedTcpClient.jar LengthPrefixedTcpClient.class

打包完成后,将.jar文件放置在jmeter的lib\ext\文件夹中(例如D:\Applications\apache-jmeter-5.6.3\lib\ext\)。
然后重新打开一次jmeter,修改TCP取样器的TCPClient classname为实现的类名LengthPrefixedTcpClient,即可使用自定义的TCPCLient。
如果测试发现没有使用这个类,可以查看jmeter文件夹的bin/jmeter.log,搜索LengthPrefixedTcpClient,如果提示这个类not found,可能步骤有误。

posted on 2025-07-28 15:25  平ping  阅读(65)  评论(0)    收藏  举报