socket协议分为TCP、UDP两种(区别与联系在此不做赘述),一种为长连接、一种为短连接。如果创建连接时在init中对应关闭连接在end中,则为长连接;如果创建关闭连接都是在action则为短连接。

在这里主要是对socket脚本调试过程中遇到的问题做一下简单记录。

Q1:发送请求内容的组装方式?

常用的有两种,数据一种是data.ws文件中存放的,一种是直接通过函数存在参数中。

第一种,data.ws中直接把请求放进去就可以了,请求内容的具体形式如(二进制、加密数据)等根据实际编写就可以。

Action()
{
int intConn; //连接成功标志
int Count_ConnFail=; //连接失败统计
int Count_NoRecv=; //返回报文为空统计
int Count_Error=; //交易失败统计 //创建连接
intConn=lrs_create_socket("socket1", "TCP", "LocalHost=0", "RemoteHost=10.10.49.1:1000", LrsLastArg); lr_start_transaction ("汇总查询"); if(intConn==) // Socket连接创建成功
{
lrs_set_send_timeout (,); // 设置发送报文的超时时间
lrs_send("socket1", "buf1", LrsLastArg); lrs_set_recv_timeout (,); // 设置返回报文的超时时间
lrs_receive("socket1", "buf2", LrsLastArg); //lrs_get_last_received_buffer ("socket1",&ActualBuffer,&NumofBytes); if(lrs_get_last_received_buffer_size ("socket1")<) // 如果系统返回报文为空
{
Count_NoRecv++;
lr_end_transaction("汇总查询",LR_FAIL);
lr_output_message ("返回报文为空。为空次数:%d",Count_NoRecv); }
else { // 系统返回报文不为空 //取ansCode:0为成功 非0为失败
lrs_save_searched_string ("socket1",LRS_LAST_RECEIVED,"ansCode","LB=<ans_code>","RB=</ans_code>",,,-);
lr_output_message ("ansCode:%s",lr_eval_string ("<ansCode>")); //取ansInfo信息:“交易成功”即成功,其他返回值均为失败
lrs_save_searched_string ("socket1",LRS_LAST_RECEIVED,"ansInfo","LB=<ans_info>","RB=</ans_info>",,,-);
//lr_output_message ("AnsInfo: %s",lr_eval_string("<ansInfo>")); if(strcmp(lr_eval_string("<ansCode>"),"")==)
{
lr_end_transaction ("汇总查询",LR_PASS);
lr_output_message ("交易结果:%s",lr_eval_string ("<ansInfo>"));
}
else
{ //交易失败
Count_Error++;
lr_end_transaction ("汇总查询",LR_FAIL); //交易失败
lr_output_message("交易结果:%s",lr_eval_string ("<ansInfo>"));
lr_output_message ("交易失败次数统计:%d",Count_Error);
}
}
}
else // Socket连接创建不成功
{
Count_ConnFail++;
lr_end_transaction ("汇总查询",LR_FAIL);
lr_output_message ("Socket 连接失败! Error code=%d。连接失败次数:%d",intConn,Count_ConnFail);
} lrs_close_socket("socket1"); return ;
}

对应的data.ws中(buf1在这里是必须的,这里只截取实际报文的一部分,buf2可只指定长度)

;WSRData  

send  buf1
"0 601<ap><head><tr_code>900001</tr_code><corp_no><CorpNo><tr_acdt>2012"
"1127</tr_acdt><tr_time>084724</tr_time><atom_tr_count>1</atom_tr_count><ch"
"annel>1</channel><sign>11111111</sign><filename>No File</filename><ogl_ser"
"ial_no> </ogl_serial_no><reserved> </reserved></head><body><start_date>201609<EndDay></start_date><start_time>090000</start_time><end_date></body></ap>" recv buf2 *
//517
//"0510 <ap><head><tr_code>920201</tr_code><corp_no> </corp_no><req_no>600<"
//"/req_no><ans_no>5230</ans_no><tr_acdt>20121112</tr_acdt><tr_time>085032</t"
//"r_time><ans_code>0</ans_code><ans_info>交易成功</ans_info><particular_code"
//">0000</particular_code><particular_code>0000</particular_code><particular_"
//"info>交易成功</particular_info></head><body><field_num>7</field_num><record_num>1</record_num></body></ap>" -

这种形式的发送数据就在data.ws中,后续对其参数化与普通的脚本没有区别。

第二种,通过sprintf函数保存内容在参数中,见下例。

Action()
{
lr_start_transaction("Action_1000");
Action_1000();
lr_end_transaction("Action_1000",LR_AUTO);
} Action_1000()
{ char szPacketContent[]; //发送包的内容
char szRecvContent[];//接收包的内容
int iSndPacketLen = ;
char szNumberOfBytesToRecv[+];
int iReceiveLen=; int iRtn = ;
char* pReceiveBuf=NULL; char *p1=NULL;
char *p2=NULL;
char ResposeCode[];
char ErrorMessage[]; //缓冲区清零
memset(szPacketContent,,sizeof(szPacketContent));
memset(szRecvContent,,sizeof(szRecvContent));
memset(szNumberOfBytesToRecv,,sizeof(szNumberOfBytesToRecv) );
memset(ResposeCode,,sizeof(ResposeCode));
memset(ErrorMessage,,sizeof(ErrorMessage));
lr_think_time(1.2); //创建服务器连接
//******************************************
iRtn = lrs_create_socket("socket0", "TCP", "LocalHost=0","RemoteHost={IP}", LrsLastArg);
//****************************************** if( != iRtn )
{
lr_error_message("Create TCP socket failed,code:%d",iRtn);
return ;
} sprintf(szPacketContent,"%s",lr_eval_string("<TransactionCode>1000</TransactionCode>"
"<IDCard>{IDCard}</IDCard>"
"<Password>111111</Password>"
"<Balance>10000000.00</Balance>"
)
); lr_start_transaction("1000_K"); //设置发送缓冲区
lrs_set_send_buffer("socket0", szPacketContent, ); iRtn = lrs_send("socket0", "buf0", LrsLastArg); //将报文发送到服务器
if( != iRtn )
{
lr_end_transaction("1000_K",LR_FAIL);
lr_error_message("Send packet failed,code:%d",iRtn);
lrs_close_socket("socket0");
return ;
} #ifdef DEBUG
lr_output_message("Send Bufffer is:%s",szPacketContent);
lr_output_message("Send Buffer Lenght is:%d",iSndPacketLen);
#endif //设置超时
lrs_set_recv_timeout(, ); sprintf(szNumberOfBytesToRecv,"NumberOfBytesToRecv=%d",); //******************************************
//用lrs_receive_ex函数来收报文 iRtn=lrs_receive_ex("socket0","buf1",szNumberOfBytesToRecv,LrsLastArg); //******************************************
if( != iRtn )
{
lr_end_transaction("4700_KKH",LR_FAIL);
lr_error_message("Receive packet failed,code:%d",iRtn);
lrs_close_socket("socket0");
return ;
} //******************************************
//lrs_get_last_received_buffer函数获得收到报文的缓冲区 iRtn=lrs_get_last_received_buffer("socket0",&pReceiveBuf,&iReceiveLen); //****************************************** if( iRtn != || NULL == pReceiveBuf )
{
lrs_free_buffer(pReceiveBuf);
lr_end_transaction("4700_KKH",LR_FAIL);
lrs_close_socket("socket0");
lr_error_message("The Content of last receive buffer is NULL");
return ; } #ifdef DEBUG
// lr_output_message("The Content of last receive buffer is:\n%s",pReceiveBuf+sizeof(int));
#endif memcpy(szRecvContent,pReceiveBuf,iReceiveLen); p1=(char*)strstr(szRecvContent,"<ResponseCode>"); p2=(char*)strstr(szRecvContent,"</ResponseCode>"); if (p1==NULL ||p2==NULL)
{ lrs_free_buffer(pReceiveBuf);
lr_end_transaction("1000_K",LR_FAIL);
lrs_close_socket("socket0");
lr_error_message("can not find ResposeCode");
return ;
} memcpy(ResposeCode,p1+,p2-p1-); if( strcmp(ResposeCode,"") == )
{
lr_end_transaction("1000_K",LR_PASS);
}
else
{
lr_end_transaction("1000_K",LR_FAIL); p1=(char*)strstr(szRecvContent,"<ErrorMessage>");
p2=(char*)strstr(szRecvContent,"</ErrorMessage>"); memcpy(ErrorMessage,p1+,p2-p1-); lr_error_message("ResposeCode is : %s\n ErrorMessage is: %s",ResposeCode,ErrorMessage);
} //释放pReceiveBuf缓冲区,因为pReceiveBuf缓冲区是Loadrunner分配的,必须显示的释放
lrs_free_buffer(pReceiveBuf); //关闭连接
lrs_close_socket("socket0"); return ;
}

对应的data.ws中(无实际的buf0内容,只有buf0、buf1的长度,buf0内容在action中生成)

;WSRData
send buf0 recv buf1 -

注意:

1、请求报文的格式问题,根据实际请求来分析。报文可通过socketTool工具实际发送看看。比如请求报文每行要分行,在LR里就需要添加\r\n。

2、如果请求报文在参数化时,无法保证所有报文的长度是固定的。这时采取哪种呢?第二种。比如取所有报文长度的最长值100,那直接参数定义为100,如果实际报文长度为80则该报文补0达到100。如果报文收发没有问题,就可以直接使用。

待补充。。。。。

LR socket协议脚本的更多相关文章

  1. LoadRunner编写Socket协议脚本方法

    本文主要介绍使用LoadRunner手工编写Windows Socket协议测试脚本的方法. 通过LoadRunner编写Windows Socket协议测试脚本,总体说来,比较简单.就像把大象放进冰 ...

  2. LR Socket接收超时TPS上不去解决方法

    在一次做项目中,由于Socket协议接收的报文会有不定长度,基本每次都会有变化,在data.ws 接收buf1有固定长度,这是在接收的实时报文会有长度不一致的问题.这时LR默认会去与接收的报文的长度及 ...

  3. 使用LR的socket协议进行进行性能测试,转解决方案

    在用LR对公司delphi开发的C/S程序进行测试时,发现只有选择socket协议可以录制代码,经研究是通过TCP/IP的方式将参数保存在buffer中发送的方式来完成操作,但由于将buffer内容参 ...

  4. 【LoadRunner】LR编写Dubbo协议脚本

    一.Dubbo服务简介 Dubbo是一个分布式服务架构,把核心业务抽取出来作为独立的服务,使前端应用能更快速和稳定的响应. Dubbo服务工作原理:服务提供方提供接口,并提供接口的实现,提供方注册服务 ...

  5. Loadrunner socket协议lrs_receive函数接收到返回数据包 仍然等待服务器返回--解决

    前段时间在使用loadrunner socket协议发送数据包到到服务器,使用lrs_receive接收服务器应答数据包,已经接收到数据包,但LR仍然在等待服务器端返回,而且日志打印显示每次接收返回都 ...

  6. 性能测试基础-SOCKET协议用例

    1.首先在进行性能测试的时候,我们要了解软件的通信协议是什么,我们使用什么协议,如何去模拟.SOCKET协议主要应用于在C/S模式的系统. 作者本人已当初做过的C/S架构的系统做的脚本录制,在上面做脚 ...

  7. 性能测试总结工作总结-基于WebService协议脚本 内置函数手动编写

    LoadRunner基于WebService协议脚本 WebService协议脚本有三种生成方式,一种是直接通过LoadRunner导入URL自动解析生成:一种是使用LoadRunner内置函数手动编 ...

  8. Loadrunner 中socket协议RecvBuffer接收到数据长度为空

    socket通讯,有两种方式,一种是建立长连接(TCP),建立后,不停的发送,接收.另外一种是建立短连接(UDP),建立连接,发送报文,接收响应,关闭连接.两种方式 server的开销不同. 今天出现 ...

  9. Loadrunner11中webservice协议脚本总结

    Loadrunner11中webservice协议脚本总结 简介     webservices协议是建立可交互操作的分布式应用程序的新平台,它通过一系列的标准和协议来保证程序之间的动态连接,其中最基 ...

随机推荐

  1. .NET Core微服务之基于Consul实现服务治理(续)

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 上一篇发布之后,很多人点赞和评论,不胜惶恐,这一篇把上一篇没有弄到的东西补一下,也算是给各位前来询问的朋友的一些回复吧. 一.Consul ...

  2. ColorUtil【Color工具类(color整型、rgb数组、16进制互相转换)】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 主要用于color整型.rgb数组.16进制互相转换(-12590395 <--> #3FE2C5 <--> ...

  3. MySQL via EF6 的试用报告

    1.如何通过 EF6 来连接 MySQL? 2.如何通过 EF6 来实现 CRUD? 2.1.Create 添加 2.2.Retrieve 查询 2.3.Update 修改 2.4.Delete 删除 ...

  4. 补习系列(12)-springboot 与邮件发送

    目录 一.邮件协议 关于数据传输 二.SpringBoot 与邮件 A. 添加依赖 B. 配置文件 C. 发送文本邮件 D.发送附件 E. 发送Html邮件 三.CID与图片 参考文档 一.邮件协议 ...

  5. 爸爸又给Spring MVC生了个弟弟叫Spring WebFlux

    情景引入 很早之前,Java就火起来了,是因为它善于开发和处理网络方面的应用. Java有一个爱好,就是喜欢制定规范标准,但自己又不善于去实现. 反倒是一些服务提供商使用它的规范标准来制造应用服务器而 ...

  6. 浅谈SpringMVC执行过程

    通过深入分析Spring源码,我们知道Spring框架包括大致六大模块, 如Web模块,数据库访问技术模块,面向切面模块,基础设施模块,核心容器模块和模块, 其中,在Spring框架的Web模块中,又 ...

  7. C# 因缺少CategoryName,而未能初始化 的解决办法

    群里一小伙伴在开发APP时遇到了问题,便截图提问 一.傻瓜式解决办法: 删除: ((System.ComponentModel.ISupportInitialize)(this.performance ...

  8. 如何在已有项目中引入FineUIMvc

    FineUIMvc简介 FineUIMvc 是基于 jQuery 的专业 ASP.NET MVC 控件库,其前身是基于 WebForms 的开源控件库 FineUI(历时9年120多个版本).Fine ...

  9. C# 反射 判断类的延伸类型

    判断类型是否被继承.实现 1.判断是否实现了指定接口 添加测试类: public class TestClass2 : TestClass1 { } public class TestClass1 : ...

  10. base64字符串转文件,以及ngImgCrop裁剪图片并上传保存到服务器示例

    base64字符串是包含文件格式的文件字符串,例如:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAgAElE ...