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. 5G网络与4G相比,有什么区别?

    5G 是 2018 年移动通信领域的热词.从中兴的芯片卡脖事件,联想 5G 投票风波再到华为频遭威胁.这些事件都引起了大家对于 5G 的关注,那么 5G 到底是什么,它和 4G 有什么区别呢? 今天就 ...

  2. Jenkins|简单Job配置|启动脚本|测试报告

    目录 1.Jenkins安装 2.Jenkins启动脚本 3.节点配置 4.任务配置 5.集成HTML测试报告 1.Jenkins安装 操作环境:Ubuntu jenkins针对windows,ubu ...

  3. Spring Boot 2.x 系列教程:WebFlux 系列教程大纲(一)

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! WebFlux 系列教程大纲 一.背景 大家都知道,Sprin ...

  4. Kubernetes知识小普及

    大部分概念Kubernetes官网都有详细介绍,Kubernetes中文官网 https://kubernetes.io/zh/docs/tutorials/kubernetes-basics/ 官网 ...

  5. etcd v3集群备份和恢复

    官方文档 https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/recovery.md 一.运行3个etcd节点 我们用 ...

  6. 浅谈Linux基本命令

    本篇文章作为Linux 入门的必备篇,主要简述Linux系统目录结构和Linux 基本Shell命令,大致内容如下: ​ 一  Linux目录及其概述 如下目录为CentOS 7目录结构 ​ 1.建立 ...

  7. Hexo优化 | 创建sitemap站点地图并向Google提交

    前言 站点地图是一种文件,您可以通过该文件列出您网站上的网页,从而将您网站内容的组织架构告知Google和其他搜索引擎.Sitemap 可方便管理员通知搜索引擎他们网站上有哪些可供抓取的网页.搜索引擎 ...

  8. T-SQL 簡易小數處理

    今天因應同事提的一則需求,寫了一段 CASE WHEN 的整數與小數處理 過程中居然踩了個雷,特此記錄下來 首先,需求如下: 當內容為整數或零時則去掉尾端的小數否則就顯示原本的小數內容 若內容為 NU ...

  9. python实现某目录下将多个文件夹内的文件复制到一个文件夹中

    现实生活中,我们经常有这样的需求,如下图,有三个文件夹,文件夹1内含有1.txt文件 文件夹2中内含有2.txt文件,文件夹3中含有3.txt文件.我们有时候需要把1.txt, 2.txt, 3.tx ...

  10. [MySQL] mysql的逻辑分层

    mysql逻辑分层:1.client ==>连接层 ==>服务层==>引擎层==>存储层 server2.连接层: 提供与客户端连接的服务3.服务层: 1.提供各种用户使用的接 ...