zoukankan      html  css  js  c++  java
  • LR socket协议脚本

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

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

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

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

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

    Action()
    {
        int intConn;                                    //连接成功标志
        int Count_ConnFail=0;                            //连接失败统计
        int Count_NoRecv=0;                                //返回报文为空统计
        int Count_Error=0;                                //交易失败统计
    
        //创建连接
        intConn=lrs_create_socket("socket1", "TCP", "LocalHost=0", "RemoteHost=10.10.49.1:1000", LrsLastArg);
    
        lr_start_transaction ("汇总查询");
    
        if(intConn==0)                            // Socket连接创建成功
            {                                
            lrs_set_send_timeout (120,0);        // 设置发送报文的超时时间
            lrs_send("socket1", "buf1", LrsLastArg);
    
            lrs_set_recv_timeout (120,0);         // 设置返回报文的超时时间
            lrs_receive("socket1", "buf2", LrsLastArg);
    
            //lrs_get_last_received_buffer ("socket1",&ActualBuffer,&NumofBytes);
    
            if(lrs_get_last_received_buffer_size ("socket1")<1)                    // 如果系统返回报文为空
            {
                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>",1,0,-1);
            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>",1,0,-1);
            //lr_output_message ("AnsInfo: %s",lr_eval_string("<ansInfo>"));
    
            if(strcmp(lr_eval_string("<ansCode>"),"0")==0)
                {
                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 0;
    }
    View Code

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

    ;WSRData 2 1
    
    send  buf1 308
        "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 500 *
        //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>"
    
    
    -1
    View Code

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

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

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

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

    ;WSRData 2 1
    send  buf0 256
    
    
    recv  buf1 256
    
    
    -1
    View Code

    注意:

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

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

    待补充。。。。。

  • 相关阅读:
    组合问题的递归实现
    递归解决全排列算法
    字符串专题练习
    Linux系统目录架构
    Linux命令行文本处理工具
    Linux扩展权限
    Linux权限机制
    Linux用户基础
    Linux文件系统挂载管理
    Sensors Grouping Model for Wireless Sensor Network*
  • 原文地址:https://www.cnblogs.com/kongzhongqijing/p/7111412.html
Copyright © 2011-2022 走看看