LR socket協議腳本

socket協議分爲TCP、UDP兩種(區別與聯繫在此不作贅述),一種爲長鏈接、一種爲短鏈接。若是建立鏈接時在init中對應關閉鏈接在end中,則爲長鏈接;若是建立關閉鏈接都是在action則爲短鏈接。服務器

 

在這裏主要是對socket腳本調試過程當中遇到的問題作一下簡單記錄。socket

 

Q1:發送請求內容的組裝方式?ide

經常使用的有兩種,數據一種是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可只指定長度)atom

;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函數保存內容在參數中,見下例。spa

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:\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 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\n 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

 

注意:code

一、請求報文的格式問題,根據實際請求來分析。報文可經過socketTool工具實際發送看看。好比請求報文每行要分行,在LR裏就須要添加\r\n。

二、若是請求報文在參數化時,沒法保證全部報文的長度是固定的。這時採起哪一種呢?第二種。好比取全部報文長度的最長值100,那直接參數定義爲100,若是實際報文長度爲80則該報文補0達到100。若是報文收發沒有問題,就能夠直接使用。

 

待補充。。。。。

相關文章
相關標籤/搜索