loadrunner之winsock协议使用总结

上一篇 / 下一篇  2012-08-16 17:07:31 / 个人分类:LoadRunner

刚进公司时,负责公司C/S项目的性能测试,作为一个刚从培训学校出来的测试生,感到即紧张又兴奋。安装完lr就像培训时候录制,等着去LR能记录下客户端与服务器之间的通信信息,然后我再去参数化,做关联……想的挺顺利的,实际上录制操作后一片空白,都说winsocket协议是万能协议,于是我尝试用winsocket协议去录制,结果还是没能成功。此时,我开始在网上搜索C/S项目性能测试的相关资料,结合与开发了解的结果,当时的项目使用的一种自定义的SMB协议,建立在TCP/IP协议基础之上,最终决定使用winsocket自己写脚本,其实在培训的时候也是用过这个协议去录制过购票程序,那时候觉得做关联着实不方便,data.ws里面的信息很难看明白。在51testing论坛中,在这里找到一些帖子,为我提供了思路。

 

高级站友tttrrryyy http://bbs.51testing.com/viewthread.php?tid=182981&from=favorites

这篇帖子为我解决C/S架构的理正了思路

 

高级站友cafard-haibinhttp://bbs.51testing.com/viewthread.php?tid=462017&extra=&page=1

这篇帖子为我开始写脚本开了一个好头,例子并不复杂,socket基本模式再清楚不过啦

 

第一步,使用wireshark抓包,通过整理挑出关键步骤的收发包,并这些关键步骤的收发包的具体格式和内容。举一个登录的例子来看

抓包内容:

0000   fe 01 00 00 00 00 00 00 00 01 00 00 00 3d 00 00  .............=..

0010   00 07 74 65 73 74 30 30 31 00 00 00 20 33 32 45  ..test001... 32E

0020   44 38 37 42 44 42 35 46 44 43 35 45 39 43 42 41  D87BDB5FDC5E9CBA

0030   38 38 35 34 37 33 37 36 38 31 38 44 34 00 00 00  88547376818D4...

0040   00 00 00 00 00 00 00 00 00 00 00                 ...........

分析格式:

0000 [fe 01]包头

0000 [00 00 00 00 00 00 00 01]包类型

0000 [00 00 00 3d]后面数据总长度

0010 [74 65 73 74 30 30 31]用户名

0010-0030 [33 32 45 44 38 37 42 44 42 35 46 44 43 35 45 39 43 42 41 38 38 35 34 37 33 37 36 38 31 38 44 34]加密后的登录密码

整理出放在data.ws里面的那些buf,并且还可使在data.ws里面进行参数化

send  buf1 75

"\xfe\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x3d"

"\x00\x00\x00\x07<username>"

"\x00\x00\x00\x20"

"<password>"

"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"

 

第二步,完成上一步的收集工作,按照cafard-haibin帖子的指导,大致能把脚本弄得七七八八。在实际单脚本运行过程中,发现还是有问题的。开启详细日志,看到LR从服务器收到的某个返回包中夹杂着心跳检测包。接收的包与预期的包大小不一致,LR就一直以为没有收到正确的包,于是一直在等。也许这里有人要说,不是有接收超时么?我一开始也是这样觉得,后来经过观察发现,接受超时默认是10s,但是这个程序每隔5S就发一个心跳检测包过来,LR就收包分析,发现还是不对,又开始新一轮10S的等待,最后导致这个用户就挂在线上,一直在做心跳检测,这个问题其实就是个粘包问题。

解决方法:我们已经知道每个包都是满足一个格式的,心跳检测也不例外,还记得报的格式么:包头+包类型+包体长度,因此在读服务器返回包时,只需先读取每个包的前14个字符,得到包体长度,再读取包体长度长的字符,这样就能将一个包成两次接收,控制大小。用到了一些winsocket函数,如lrs_receive_exlrs_save_param等等。LoadRunner Winsocket协议知识总结.pdf》,还有LRF1也很好用哟。

第三步,准备基础数据,并做好备份

 

第四步,虚拟IP地址

注意事项:

1设置虚拟IP的本机先设置为静态IP,而非DHCP

2  C类至多只有254个虚拟IP可用,当超出这个数目时,可以将子网设置为B类子网

当不需要虚拟IP时,可以将网络设置为DHCP自动获取,即可释放那些虚拟IP

 

第五步,设置场景,添加服务器的监控计数器

项目服务器的操作系统FreeBSD,具体设置参见这篇文档:

http://www.51testing.com/?uid-464024-action-viewspace-itemid-832199

 

第六步,多机联合运行

 

1vuser_init

#include "lrs.h"

         int rc;

         int i=0;

    char *ip;

 

void waiting(int time){

                   int tmp=0;

                   while(tmp<time){

                            lrs_receive("socket0", "buf8", LrsLastArg);

                            lrs_send("socket0", "buf7", LrsLastArg);

                            tmp++;

                   }

}

 

vuser_init()

{

    lrs_startup(257);    

         ip=lr_get_vuser_ip();

 

         if(ip)

                   lr_vuser_status_message("The ip address is %s",ip);

         else

                   lr_vuser_status_message("IP spoofing disabled %s",ip);

        

         lr_message("用户名是%s",lr_eval_string("<username>"));

         lr_start_transaction("login");

         lrs_set_connect_timeout(100, 0);

 

//     与服务器8900端口建立连接,若返回值为0,说明连接建立成功,否则连接建立失败

         rc = lrs_create_socket("socket0", "TCP", "LocalHost=0","RemoteHost=192.168.0.5:8926",  LrsLastArg);

 

     if (rc != 0 ) {

                   lr_end_transaction ("login", LR_FAIL);

            lr_output_message("错误:与服务器8926端口建立连接失败!");        

                   return -1;

         }

         else{

                   lr_output_message("与服务器建立连接成功!");

                   //发送登录请求包

                   lrs_send("socket0", "buf1", LrsLastArg);

                   do{

                            lrs_receive_ex("socket0", "buf2", "NumberOfBytesToRecv=14", LrsLastArg);

                            lrs_save_param("socket0",NULL,"length",13,1);

                            lrs_hex_string_to_int(lr_eval_string("<length>"),1,&i);

/*            调试信息

                            lr_output_message("bufferlength=%d",i);

*/

                            if (i==20) {

                                     lr_end_transaction ("login", LR_PASS);

                                     lrs_receive_ex("socket0", "buf3", "NumberOfBytesToRecv=20", LrsLastArg);

                            }

                            else if(i==8){

                                     lr_end_transaction ("login", LR_FAIL);

                                     lrs_receive_ex("socket0", "buf4", "NumberOfBytesToRecv=8",LrsLastArg);

                                     return -1;

                            }

                            else if(i==0){

                                     lrs_send("socket0", "buf7", LrsLastArg);

                            }

                            else{

                                     lr_end_transaction ("login", LR_FAIL);

                                     return -1;

                            }

                   }while(i==0);

 

                   lrs_set_recv_timeout(7,0);

                   lrs_set_recv_timeout2(2,0);

                  

                   lrs_receive("socket0", "buf8", LrsLastArg);

                   lrs_send("socket0", "buf7", LrsLastArg);

                  

                   //     模拟心跳检测,延长在线时间

                   waiting(3);

         }

}

 

 

2 Action

#include "lrs.h"

 

Action()

{

         lrs_set_recv_timeout(7,0);

         lrs_set_recv_timeout2(2,0);

 

         lrs_receive("socket0", "buf8", LrsLastArg);

         lrs_send("socket0", "buf7", LrsLastArg);

 

         //注册文件:13,14

         lr_rendezvous("ren_register");

         lr_start_transaction("register");

         lrs_send("socket0", "buf13", LrsLastArg);

 

         do{

                   lrs_receive_ex("socket0", "buf2", "NumberOfBytesToRecv=14", LrsLastArg);

                   lrs_save_param("socket0",NULL,"length",13,1);

                   lrs_hex_string_to_int(lr_eval_string("<length>"),1,&i);

 

         //     调试信息

         //      lr_output_message("bufferlength=%d",i);

 

                   if (i==87) {

                            lr_end_transaction("register",LR_PASS);

                            lrs_receive_ex("socket0", "buf14", "NumberOfBytesToRecv=87",LrsLastArg);

                   //     关联获取uuid

                            lrs_save_param("socket0",NULL,"uuid",12,36);

                   //      lr_output_message ("uuid: %s", lr_eval_string("<uuid>"));

                   }

                   else if(i==0){

                            lrs_send("socket0", "buf7", LrsLastArg);

                   }

                   else {

                            lr_end_transaction("register",LR_FAIL);

                            return -1;

                   }

         }while(i==0);

 

         //心跳检测

         waiting(3);

 

         //打开文件:15,16

         lr_rendezvous("ren_openfile");

         lr_start_transaction("openfile");

         lrs_send("socket0", "buf15", LrsLastArg);

         do{  

                   lrs_receive_ex("socket0", "buf2", "NumberOfBytesToRecv=14", LrsLastArg);

                   lrs_save_param("socket0",NULL,"length",13,1);

                   lrs_hex_string_to_int(lr_eval_string("<length>"),1,&i);

 

         //     调试信息

         //      lr_output_message("bufferlength=%d",i);

 

                   if (i==91) {

                            lr_end_transaction("openfile",LR_PASS);

                            lrs_receive_ex("socket0", "buf16", "NumberOfBytesToRecv=91",LrsLastArg);

                   }

                   else if(i==0){

                            lrs_send("socket0", "buf7", LrsLastArg);

                   }

                   else {

                            lr_end_transaction("openfile",LR_FAIL);

                   }

         }while(i==0);

 

         waiting(3); //心跳检测

 

         //文件授权:5,6

         lr_rendezvous("ren_grant");

         lr_start_transaction("grant");

         lrs_send("socket0", "buf5", LrsLastArg);

         do{

                   lrs_receive_ex("socket0", "buf2", "NumberOfBytesToRecv=14", LrsLastArg);

                   lrs_save_param("socket0",NULL,"length",13,1);

                   lrs_hex_string_to_int(lr_eval_string("<length>"),1,&i);

         //     调试信息

         //      lr_output_message("bufferlength=%d",i);

 

                   if (i==90) {

                            lr_end_transaction("grant",LR_PASS);

      &nb

TAG:

 

评分:0

我来说两句

日历

« 2024-03-29  
     12
3456789
10111213141516
17181920212223
24252627282930
31      

数据统计

  • 访问量: 20817
  • 日志数: 24
  • 书签数: 1
  • 建立时间: 2012-05-13
  • 更新时间: 2021-10-28

RSS订阅