JMeter TCP Sampler报ReadException读取服务器错误如何解决
报错根因分析
该报错为JMeter TCP Sampler读取服务端响应失败触发,已读取到765字节但未检测到预设的响应结束标识,最终抛出异常,核心原因分为3类:
- EOL配置不匹配:你当前使用默认的
TCPClientImpl实现类,该类依赖EOL(结束字节)判断响应是否结束,你配置的EOL值为0(对应ASCII空字符),但服务端返回的765字节响应中没有携带该结束标识,JMeter持续等待结束标识直到触发异常。 - 请求构造逻辑错误:你当前的Beanshell脚本拼接请求时,是将每行文件内容追加到初始换行符的前方,最终请求体结构为
[最后一行文件内容]...[第一行文件内容]\n,属于倒序拼接,不符合绝大多数TCP服务的请求格式要求,可能导致服务端返回异常报文或提前断开连接。同时脚本未关闭IO流,会出现资源泄露,长时间运行会导致连接异常。 - 连接配置冲突:你开启了连接复用(Re-use connection=Yes)但设置不主动关闭连接(Close connection=No),若上一次请求的残留数据未读取完成、或服务端主动断开空闲连接,会导致后续读取失败;SO_LINGER设为0会强制复位连接,可能导致响应数据未完全传输就被断开。
解决方案
- 修正EOL及TCPClient实现类配置
- 先确认TCP服务端的响应结束规则:如果响应以换行符结束,将EOL值改为10(ASCII换行符的十进制值);如果响应是「长度前缀+报文内容」的格式,直接将TCPClient classname改为
LengthPrefixedBinaryTCPClientImpl,无需配置EOL;如果是自定义结束规则,可以自行实现TCPClient接口适配。 - 临时验证可以使用
BinaryTCPClientImpl实现类,清空EOL配置,先确认服务端返回的原始字节是否正常。
- 先确认TCP服务端的响应结束规则:如果响应以换行符结束,将EOL值改为10(ASCII换行符的十进制值);如果响应是「长度前缀+报文内容」的格式,直接将TCPClient classname改为
- 重构请求预处理脚本
- 替换Beanshell PreProcessor为JSR223 PreProcessor,选择Groovy语言,性能和稳定性远高于Beanshell,参考脚本如下:
def textToSend = new StringBuilder() def file = new File("C:/Users/prakashr/Desktop/prakash.txt") file.eachLine { line -> textToSend.append(line).append("\n") } sampler.setRequestData(textToSend.toString()) log.info("Text :${textToSend}")
- 若你确实需要倒序拼接文件内容,可以调整为
textToSend.insert(0, line + "\n")即可。
- 调整TCP连接参数
- 若无需复用连接,将Re-use connection改为No,Close connection改为Yes,避免连接残留问题
- SO_LINGER改为-1或留空,使用系统默认的连接关闭逻辑,避免强制断开丢数据
- 若服务端响应较慢,可将Response超时适当调整为20000~30000毫秒
内容的提问来源于stack exchange,提问作者Prakash Ranasinghe
相关产品推荐
相关产品推荐

