zoukankan      html  css  js  c++  java
  • 用LoadRunner编写socket应用的测试脚本

            LoadRunner提供了很好的对socket应用的支持,用户可以通过录制方法完全获得客户端发送和接收的数据,然后在录制的基础上对相应的数据进行参数化和关联等处理。

            但在有些情况下(例如,客户端程序没有windows上的版本),我们就很难通过录制达成生成脚本的目标了。但如果我们能够完全知晓服务端和客户端的交互过程,完全手工编写一个测试脚本也并不是一件特别困难的事情。

           在本文中,我们以一个实际的例子说明如何根据服务端和客户端交互的过程,用LoadRunner自行编写相应的脚本。

            以下是服务端工作线程的代码:
    DWORD WINAPI mythread( LPVOID lpParameter)    //客户线程
    {
        
    struct My my;
        memcpy(
    &my,lpParameter,sizeof(My));    
        printf(
    "One client connect!\n");
        
    char str1[1024];            //接收字符串
        char str2[1024];
                            
        
    int i;
        i
    =recv(my.skt,str1,sizeof(str1),0);    //接收客户请求
        str1[i]=0;

        
    char *filename;
        filename
    =new char[255];
        
    for(int j=2;j<i;j++)            //获得文件名
        {
            filename[j
    -2]=str1[j];
        }
        filename[i
    -2]=0;
       

        
    if (str1[0]=='S')
        {
            printf(
    "The file name : %s\n",filename);
            ofstream 
    out(filename);                //创文件流   
            if (!out)
            {
                printf(
    "cannot open file.\n");        //文件是否正确打开,打开错误则退出
                send(my.skt,"q",1,0);            //向客户发送退出信息
                closesocket(my.skt);            //解除客户连接;
                return 0;
            }
            str2[
    0]='O';                       
            str2[
    1]='K';
            str2[
    2]=0;
            send(my.skt,str2,strlen(str2),
    0);        //回复OK信息

            i
    =recv(my.skt,str1,sizeof(str1),0);        //接收文件长度
            str1[4]=0;
           
            
    int len;
            len
    =str1[0]*1000+str1[1]*100+str1[2]*10+str1[3];
            printf(
    "The File lenght is: %d Byte\n",len);
           
            
    for(int j=0;j<len;j++)
                {
                    
    char str[1];
                    i
    =recv(my.skt,str,sizeof(str),0);//接收文件,按字节接收,接收字符串为2个字节
                    str[i]=0;
                    
    out.put(str[0]);
                }

            
    out.close();                    //关闭文件
            printf("over!One client quit!\n");        //接收文件完毕
            closesocket(my.skt);                //解除此客户连接
            return 0;
        }

        
    if (str1[0]=='R')
        {       
           
            ifstream 
    in(filename);
            
    if (!in)
            {
                printf(
    "cannot open file or file not exist.\n");    //文件是否正确打开,打开错误则退出
                send(my.skt,"q",1,0);                    //向客户发送退出信息
                closesocket(my.skt);                    //解除客户连接;
                return 0;
            }
            
    char ch;
            
    int len=0;
            
    while(in.get(ch))
            {
                len
    ++;                            //get file lenght
            }
            
    in.close();
            str2[
    0]='O';
            str2[
    1]='K';
            str2[
    2]=len/1000;                       
            str2[
    3]=(len%1000)/100;
            str2[
    4]=(len%100)/10;
            str2[
    5]=len%10;
            printf(
    "%s",str2);
            send(my.skt,str2,
    6,0);                        //发OK+文件长度

            
    in.open(filename);
            
    if (!in)
            {
                printf(
    "cannot open file or file not exist.\n");    //文件是否正确打开,打开错误则退出
                send(my.skt,"q",1,0);                    //向客户发送退出信息
                closesocket(my.skt);                    //解除客户连接;
                return 0;
            }

            
    while(in.get(ch))                        //发文件
            {               
                
    char str[1];
                strcpy(str,
    "");
                str[
    0]=ch;
                str[
    1]=0;
                send(my.skt,str,
    1,0);                    //发送一个字符
            }
            
    in.close();
            printf(
    "over,One client quit!\n");                //传输文件完毕
            closesocket(my.skt);                        //解除此客户连接
            return 0;
        }

        printf(
    "Bad command!\n");
        closesocket(my.skt);
        
    return 0;
    }

            从这段代码中可以看到,当客户端和服务端建立连接后,客户端会先向服务端发送一个请求,该请求的第一个字节是大写的“S”或是“R”,分别向服务端写文件或是从服务端读取文件。从第三个字节开始,后面的内容是请求文件的文件名。

            服务端在接收到客户端的请求后,根据请求的类型,如果是“S”,则打开指定的文件,并返回一个字符串“OK”;如果是“R”,则打开指定的文件并向客户端发送“OK”+“文件长度”。

            随后,如果是“S”,则由客户端发送写入的文件长度和文件内容给服务端;如果是“R”,则向客户端发送文件的内容。

            到此我们已经完全明了了客户端和服务端的交互过程,因此,我们可以尝试在LR中建立一个脚本用户模拟客户端行为。

            下面我们以“S”的处理过程为例编写脚本。

            1、打开VUGen应用;
            2、新建脚本,选择“windows sockets”协议,不需录制;
            3、在Action Section中增加以下内容:
        //建立到服务端的连接
        lrs_create_socket("socket1","TCP","RemoteHost=127.0.0.1:8000",LrsLastArg);
       
        
    //发送“S”和文件名
        lrs_send("socket1""buf0", LrsLastArg);
        lrs_receive(
    "socket1""buf1", LrsLastArg);
       
        
    //发送要写入的数据的长度
        lrs_send("socket1""buf2", LrsLastArg);

        
    //发送数据内容
        lrs_send("socket1""buf3", LrsLastArg);
       
        
    //关闭连接
        lrs_close_socket("socket1");
       
            4、这样就成功的描述了整个交互过程,但还没有给出实际要发送的数据。在采用“Windows Sockets”协议的脚本中,实际发送的数据存放在data.ws Section中,因此,打开该Section,直接输入:
    send  buf0 7
        
    "S"
        
    "\x00"
        
    "1.txt"

    recv buf1 
    2
        
    "OK"

    send buf2 
    3
        
    "\x00"
        
    "\x00"
        
    "\x02"
        
    "\x00"

    send buf3 
    20
        
    "12345678901234567890"

            每个发送和接收的数据包在这里都有登记,“send”和“recv”表示数据的方向;“buf0”等表示数据包的描述,和脚本中的内容对应;接下来的一个整数表示数据包的长度;然后是数据包的内容,“\x00”表示16进制的00。

            该脚本描述了客户端向服务端请求写入一个文件1.txt,文件内容为“12345678901234567890”的过程。

            以下是脚本和服务端程序(可执行文件)的下载链接,读者可以下载到本地自行试验。

           下载服务端程序

           下载脚本

           ==========================================================================
           更多精彩LoadRunner文章,请见 关河@与谁同坐轩 LoadRunner栏目

     
  • 相关阅读:
    POJ 3186 Treats for the Cows
    HDU 1226 超级密码| NYOJ 929 密码宝盒
    POJ 1661 Help Jimmy
    POJ 1458 Common Subsequence
    POJ 1015 Jury Compromise
    window.history,页面中的返回按钮
    网站新功能引导镂空效果
    HTML5存储
    JSON对象
    点击超链接,将页面中某个数据传到另一个页面
  • 原文地址:https://www.cnblogs.com/guanhe/p/440190.html
Copyright © 2011-2022 走看看