Loadrunner 中socket协议RecvBuffer接收到数据长度为空
socket通讯,有两种方式,一种是建立长连接(TCP),建立后,不停的发送,接收。另外一种是建立短连接(UDP),建立连接,发送报文,接收响应,关闭连接。两种方式 server的开销不同。
今天出现问题:不管是创建TCP还是UDP连接,发送数据后,接收到数据的长度均为空值。
我的代码如下:
wireshark抓包查看到的结果(有接收到服务发送过来的数据):
运行时查看Loadrunner中打印日志:
多次修改代码后,最后修改接收的buffer 的长度,终于接收到数据
总结:之前看过一篇文章,如果接收到的数据长度不固定,可以指定buffer的数据长度为“*”。 现在才明白,原来 “*” 表示不接收数据 。花费一天的时间,终于搞定。
对于recvbuffer数据长度不一致的问题,或许可以参考http://blog.sina.com.cn/s/blog_6bdd0e1d0101b13r.html 这篇文章。copy 内容如下:
使用LoadRunner录制socket协议的脚本,会发现每个请求都会发送和接受一定长度的数据流,即send buffer和recv buffer;这两个buffer后面都会有个数字,这个数字表示buffer的长度,是一个固定的值。当做性能测试时,执行每次请求响应的数据很多时候是不定长的,如果recv buffer的长度与响应的数据长度不一致,脚本会报错,有两种方法可以解决这个问题:
1、造数据,使响应的数据长度在每次不同请求中都一样。但实际上,方法1是有局限性的,也就是说有些请求通过造数据也不能使响应的数据长度一致,那么我们可以采用方法2。
2、自定义函数,动态解析并接受不定长响应数据流。
以下详细介绍下方法2,以举例讲解的方式来介绍:
【业务场景】:用户进行登录操作,每次登录的响应数据由于被加密压缩后才返回的缘故,导致长度不一致。
【协议简介】:用户登录操作采取的协议是自定义协议,协议头中第5,6个byte保存的是整个响应流的长度。
【自定义函数的思路】:先接受响应数据中的前6个bytes,然后取5,6位上的字节转换成int类型,得到整个响应流的长度,从而计算出剩下未被接受的数据长度,再接受剩下的数据。
【代码实现】:
第一部分,录制后未经修改的脚本如下:
- Action()
- {
- lr_start_transaction("login");
- lrs_create_socket("socket6","TCP","RemoteHost=172.16.4.16:1122", LrsLastArg);
- //登录请求
- lrs_send("socket6", "buf1",LrsLastArg);
- lrs_receive("socket6","buf2",LrsLastArg);
- lrs_close_socket("socket6");
- lr_end_transaction("login",LR_AUTO);
- return 0;
- }
- send buf1 49
- "\x00\x00"
- recv buf2 291 //每次请求的响应数据长度不一定是291个字节
- #include "lrs.h"
- int custom_lrs_receive(char *sock_desc, char *buf_desc,void *dummy)
- {
- int rc;
- int buf_len = 6;
- char szBytesLength[30], *buf = NULL, *pszError, *pszLastChar;
- rc = lrs_receive_ex(sock_desc, buf_desc, "NumberOfBytesToRecv=6", LrsLastArg);
- if (rc != 0) //正常情况下函数返回为0,非0表示函数有错误
- {
- lr_error_message("Receive 6 bytes failed. The error code = %d", rc);
- return -1;
- }
- //判断前6个字节是否接受成功
- lrs_get_last_received_buffer(sock_desc, &buf, &buf_len);
- if (buf == NULL || buf_len != 6)
- {
- lr_error_message("receive of %s failed", buf_desc);
- return -1;
- }
- sprintf (szBytesLength, "NumberOfBytesToRecv=%d", fiFromHexBinToInt(buf) - 6);
- //调用另一个自定义函数:计算总长度的函数
- lr_debug_message(LR_MSG_CLASS_FULL_TRACE, "!!!! Bytes length = %s", szBytesLength);
- rc = lrs_receive_ex(sock_desc, buf_desc, szBytesLength, LrsLastArg);
- if (rc != 0)
- return -1;
- return 0;
- }
- int fiFromHexBinToInt(char *szBuffer)
- {
- int i, j, iIntValue = 0, iExp = 1;
- //一个字节一个字节的取值,循环2次,分别取第6位,第5位上的字节
- for( i = 1; i >= 0; i--)
- {
- iExp = 1;
- //从16进制字节流转换成int类型:2个byte4个bit,每个字节的低位分别需要乘以16的0次方和16的2次方;
- for (j = 2; j > i*2; j--)
- iExp *= 16;
- iIntValue += (szBuffer[i+4] & 0x0000000f) * iExp + ((szBuffer[i+4] & 0x000000f0) >> 4) * iExp * 16;
- }
- lr_output_message("the length is %d", iIntValue);
- return iIntValue;
- }
- Action()
- {
- lr_start_transaction("login");
- lrs_create_socket("socket6", "TCP", "RemoteHost=172.16.4.16:1122", LrsLastArg);
- // 登录请求
- lr_think_time(5);
- lrs_send("socket6", "buf1", LrsLastArg);
- custom_lrs_receive("socket6", "buf2", LrsLastArg); //自定义函数接受不定长数据流
Loadrunner 中socket协议RecvBuffer接收到数据长度为空的更多相关文章
- Loadrunner中socket协议中的三个关联函数
这3个函数其实都可以动态获取运行中收到的数据包中的数据,只要跟在要获取的收取数据包脚本后面即可.其中:lrs_save_searched_string和lrs_save_param如果buf_desc ...
- 自行控制loadrunner的socket协议性能测试 (转)
一前言 二任务的提出 三实现方案讨论 四技术要点讲解 如何开始录制一个最简单的收发数据包脚本 写日志文件 一行一行读数据包文件 字符串转换为十六进制数据包 发送自己定义的数据包 接收数据包到自定义缓冲 ...
- LoadRunner中winsocket协议学习
首先让我们先看一下loadrunner- winsock 函数 一览表: lrs_accept_connection 接受侦听套接字连接 lrs_close_socket 关闭打开的套接 ...
- LoadRunner编写Socket协议脚本方法
本文主要介绍使用LoadRunner手工编写Windows Socket协议测试脚本的方法. 通过LoadRunner编写Windows Socket协议测试脚本,总体说来,比较简单.就像把大象放进冰 ...
- loadrunner使用socket协议来实现客户端对服务器产生压力实例。(通过发送心跳包,达到连接多个客户端的目的)
#include "lrs.h" vuser_init(){ char *ip; int handler; //编写获取LR分配的Vuser IP函数,将IP保存在ip变量中. i ...
- AJAX中使用post,get接收发送数据的区别
如何发起请求 xhr.send(); 备注: 如果是get方式,send()命令中不用写任何参数 传递的数据可以写在url中,服务器用$_GEET["参数名"]接收 如果是post ...
- loadrunner socket协议问题归纳(3)
摘要:通过实例讲解loadrunner中的socket协议性能测试的一种测试方法,如何不依赖loadrunner既定规则,自行控制收发数据包 关键词:Loadrunner,socket,自行控制,收发 ...
- loadrunner socket协议问题归纳(0)
一.概述 Loadrunner拥有极为丰富的工具箱,供予我们制造出各种奇妙魔法的能力.其中就有此次要讨论的socket套接字操作. 二.socket概述 soc ...
- 品味性能之道<九>:利用Loadrunner编写socket性能测试脚本简述
一.概述 Loadrunner拥有极为丰富的工具箱,供予我们制造出各种奇妙魔法的能力.其中就有此次要讨论的socket套接字操作. 二.socket概述 ...
随机推荐
- JavaScript Function.call() 函数详解
语法 functionObject.call( [ thisObj [, arg1 [, arg2 [, args...]]]] ) call()函数用于调用当前函数functionObject,并可 ...
- HTML学习笔记 w3sCss盒子模型应用案例(div布局) 第十一节 (原创) 参考使用表
* { margin: 0px; padding: 0px; } .top { width: 100%; height: 50px; background-color: antiquewhite; } ...
- 【Kafka源码】ReplicaManager启动过程
在KafkaServer启动过程的入口中,会启动Replica Manager,众所周知,这是一个副本管理器.replica在Kafka中扮演的角色很重要,是保证消息不丢失的一个重要概念. repli ...
- Adobe Audio 分轨录音教程(需要KX,Live机架)
一.需要的硬件和软件 1. 创新5.1声卡或7.1声卡: 2. 已安装KX驱动和Live机架,经过测试安装后需要重启电脑才能生效. 3. 已安装Adobe Audition 3.0 二.测试环境 WI ...
- 阿里云ecs初始化磁盘后远程连接不到服务器
阿里云初始化磁盘后远程连接不到服务器 报错: WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! ... 原因:阿里云ecs第一次链接服务器之后会在本地电 ...
- 结合GET(),POST()实现一个简单、完整的服务器
复习一下: 基础模块 作用 fs fs模块用于对系统文件及目录进行读写操作 http 创建服务器.e.g.http.createServer(); queryString 把url带的参数串转化为数组 ...
- Oracle 存储过程的导出导入序列的导出
昨天发布网站,需要将oracle的存储过程导出来,再在新的电脑加上去.登陆—>工具—>导出用户对象—>选取需要导出的存储过程—>导出 保存格式为.sql.当然利用该种方法也可以 ...
- Redis全面介绍
最近重新认识了一下Redis,借着这个机会,也整理一篇算是比较详尽和全面的文章吧. 缓存 缓存就是数据交换的缓冲区(称作Cache)——摘自百度百科.无论是在计算机硬件体系结构还是软件体系结构中, ...
- bootstrap导航栏.nav与.navbar区别
刚刚看了bootstrap的导航栏,发现有点弄混了,现在来整理一下: 一.简单的ul,li组成的导航: <ul class="nav nav-pills justify-content ...
- JVM菜鸟进阶高手之路十四:分析篇
转载请注明原创出处,谢谢! 题目回顾 JVM菜鸟进阶高手之路十三,问题现象就是相同的代码,jvm参数不一样,表现的现象不一样. private static final int _1MB = 1024 ...