文档章节

LoadRunner中winsocket协议脚本回放时的mismatch问题处理方法

我爱睡觉
 我爱睡觉
发布于 2017/06/24 16:06
字数 1171
阅读 27
收藏 0

使用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);

// 登录请求
lr_think_time(5);
    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"
"¾¸"
"\x00"
"1"
"\x00"
" "
"\xc2"
"\t"
"\x00\xa7\xff\xd3\x00\x00\x00"
"\n"
"<fname>"
"\x00\xa7\xff\xd4\x00\x00\x00"
"\r"
"\x00\x00"
"1"
"\x00"
"2"
"\x00"
"3"
"\x00"
"4"
"\x00"
"5"
"\x00"
"6"

recv  buf
2 291           //每次请求的响应数据长度不一定是291个字节

【上述脚本的问题】:

recv buf2 291 后面的这个数字表示收到的buffer长度,这个长度在这里就固定死了,也就说每次执行这个脚本的时候都会按这个长度来接受解析响应数据,如果实际的响应数据长度与这个长度不一致会报以下错误:

Action.c(xx): Mismatch in buffer's length (expected 291 bytes, 295 bytes actually received, difference in 4 bytes)


第二部分,自定义函数和录制后修改的脚本如下:

为了能够动态接收响应数据,我们自定义了一个接收函数,如下:

  #include "lrs.h"

/*******************************************************************************

*自定义函数,用于动态接受返回的buffer

*0-6个字节是协议头的一部分,5-6个字节是整个响应包的长度

* 1.首先接受6个字节,并解析出第5,6个字节;

* 2. 计算出整个响应包的长度:length,并计算出剩下的长度:length-6;

* 3. 接受剩下的数据流;

********************************************************************************/
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;

/* 
* Get package header  0-6个bytes, [5..6] bytes  is package length 
*/

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;

} /* Receive failed */


//判断前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;
}

/* Compute buffer length */
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) /* Receive failed */
return -1;

return 0;
}


/* 
* 解析szBuffer中的5-6个字节,并转换成int类型
*/
int fiFromHexBinToInt(char *szBuffer)
{
int i, j, iIntValue = 0, iExp = 1; 
/*lr_output_message("the szBuffer is %d %d", 
szBuffer[5] & 0x000000ff,((szBuffer[6] & 0x000000ff));*/

for( i = 1; i >= 0; i--)      //一个字节一个字节的取值,循环2次,分别取第6位,第5位上的字节
{
iExp = 1;

for (j = 2; j > i*2; j--)    //从16进制字节流转换成int类型:2个byte4个bit,每个字节的低位分别需要乘以16的0次方和16的2次方;

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);    //自定义函数接受不定长数据流

     lrs_close_socket("socket6");

lr_end_transaction("login", LR_AUTO);

    return 0;

}


这样就ok了。对于使用这套协议的所有接口,该自定义函数可通用。


本文转载自:http://blog.csdn.net/rachel_luo/article/details/7912468

我爱睡觉
粉丝 3
博文 2120
码字总数 0
作品 0
南昌
私信 提问
loadrunner跑场景的时候出现:Abnormal termination, caused by mdrv process termination

1.问题 loadrunner跑场景的时候出现:Abnormal termination, caused by mdrv process termination。 备注:我使用的是RTE协议录制的脚本。 2.一些资料 2.1关于mdrv.exe意外终止的可能出现情况...

jeffsui
2013/12/04
7.3K
0
开启loadrunner测试之门

软件要测试,现在用的最多的测试软件是loadrunner,而非qtpLoadRunner,英语字面上进行理解就是负载跑步者,为什么这么说呢?对于从事IT软件行业的工作者如开发人员和测试人员来说一定不会感到...

crossmix
2015/03/31
119
0
Loadrunner通过ssh连接linux进行hadoop基准测试

版权声明:本文为博主原创文章,未经博主允许不得转载。欢迎访问我的博客 https://blog.csdn.net/smooth00/article/details/73796622 Loadrunner通过ssh连接调用hadoop的测试Jar包进行基准测...

smooth00
2017/06/27
0
0
ubuntu loaderrunner 压力测试

安装portmap服务 [plain]view plaincopy sudo apt-get install portmap 开启portmap sudo /etc/init.d/portmap restart 安装rstatd: 下载rstatd组件,下载地址:http://rstatd.sourceforge......

quanpower
2014/06/17
434
0
JavaVuser脚本开发-环境搭建

众所周知,loadrunner可以使用多种协议进行性能测试。这里不得不提到JavaVuser协议。 你是否已经厌烦了在loadrunner脚本开发中,使用各种c函数进行复杂的字符串拼接,解析报文? 那么为什么不使...

jeffsui
2014/11/11
275
0

没有更多内容

加载失败,请刷新页面

加载更多

OpenStack 简介和几种安装方式总结

OpenStack :是一个由NASA和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenSta...

小海bug
昨天
6
0
DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
昨天
6
0
数据库中间件MyCat

什么是MyCat? 查看官网的介绍是这样说的 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务、ACID、可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵...

沉浮_
昨天
7
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
昨天
9
0
常用物流快递单号查询接口种类及对接方法

目前快递查询接口有两种方式可以对接,一是和顺丰、圆通、中通、天天、韵达、德邦这些快递公司一一对接接口,二是和快递鸟这样第三方集成接口一次性对接多家常用快递。第一种耗费时间长,但是...

程序的小猿
昨天
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部