06月12, 2014

Linux下Loadrunner建立socket连接方法

Loadrunner已经成为广泛使用的性能测试工具,而多数人都是在windows环境下进行压力测试,这就会有很多的局限性。

比如想使用Loadrunner对HandlerSocket做一次性能测试,这种需要建立Socket连接的大多测试人员很快会想起使用LR支持的WinSocket协议,里面内置了很多socket操作函数,很方便。但是WinSocket协议只能在windows环境下运行,首先需要对测试环境的tcp/ip连接数情况进行测试,确保你的测试机、被测试机上不存在TCP/IP连接数限制,或者其他问题等等,Windows xp、Windows server 2003的最大TCP/IP连接数都有限制,如果更改还要去修改注册表等。

#include “lrs.h”

vuser_init()  
{  
lrs_startup(257);  
lrs_create_socket (“socket1″,”TCP”,”RemoteHost=10.131.100.21 :9994″,LrsLastArg);

return 0;

}

#include “lrs.h”

Action()  
{

lr_start_transaction(“HandlerSocket”);

lrs_set_receive_option (EndMarker,StringTerminator,”\n” );

lrs_send (“socket1″,”buf1”,LrsLastArg);

lrs_receive (“socket1″,”buf2”,LrsLastArg);

if(memcmp(lrs_get_received_buffer (“socket1″,0,4,NULL),”0\t1\n”,4)==0)

{  
lrs_send (“socket1″,”buf3”,LrsLastArg);

lrs_receive (“socket1″,”buf4”,LrsLastArg);

if(memcmp(lrs_get_received_buffer (“socket1″,0,4,NULL),”0\t4\t”,4)==0){

lr_end_transaction(“HandlerSocket”, LR_PASS);  
}else{  
lr_end_transaction(“HandlerSocket”, LR_FAIL);  
}

}else{  
lr_end_transaction(“HandlerSocket”, LR_FAIL);  
}  
return 0;  
}

#include “lrs.h”  
vuser_end()  
{  
lrs_close_socket (“socket1”);  
lrs_cleanup();

return 0;  
}

;WSRData 2 1

send buf1 100  
“P 1 mem_test sbtest PRIMARY id,k,c,pad\n”

recv buf2 40\t1\n”

send buf3 1001 = 1 <id> 1 0\n”

recv buf4 40\t4\t”

测试过程中我们发现被测试服务器根本压不上去,资源很空闲,原因就是建立的socket连接很有限。这时我们会想到强大的Linux系统,它允许建立的TCP/IP连接数很大,而且修改很方便。但是Loadrunner在linux下又不支持WinSocket协议,那我就为LR编译一个Linux下的扩展好了,大家都知道Windows下的dll动态连接库可以用lr_load_dll()函数加载,那linux下的.so文件一定可以用这个函数来加载,这样就和windows下的用法一样了,问题就解决了,首先用C写好linux sokcet建立连接、发送请求、接收返回、关闭连接的方法,然后编译成.so文件。

handlersocket.c文件代码:

#include <unistd.h>  
#include <sys/types.h> /* basic system data types */  
#include <sys/socket.h> /* basic socket definitions */  
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */  
#include <arpa/inet.h> /* inet(3) functions */  
#include <netdb.h> /*gethostbyname function */

#include <stdlib.h>  
#include <errno.h>  
#include <stdio.h>  
#include <string.h>

#define MAXLINE 1024

int opensocket(char *ip,int port)  
{  
int connfd;  
char * servInetAddr = ip;  
int servPort = port;  
// char dataBuffer[MAXLINE];

struct sockaddr_in servaddr;

connfd = socket(AF_INET, SOCK_STREAM, 0);

bzero(&servaddr, sizeof(servaddr));  
servaddr.sin_family = AF_INET;  
servaddr.sin_port = htons(servPort);  
inet_pton(AF_INET, servInetAddr, &servaddr.sin_addr);

if (connect(connfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {  
perror(“connect error”);  
return -1;  
}else{  
//return 1;  
return connfd;  
}  
}  
void closesocket(int connfd){  
close(connfd);  
}

int msgsend(int connfd,char *msg){  
char dataBuffer[MAXLINE];  
bzero(dataBuffer,MAXLINE+1);  
strncpy(dataBuffer,msg,strlen(msg));  
int errSend = send(connfd,dataBuffer,strlen(dataBuffer),0);  
if(-1 == errSend)  
{  
return -1;  
}else{  
return 1;  
}  
}  
int cmprecvmsg(int connfd,char *msg,int len){  
char dataBuffer[MAXLINE];  
bzero(dataBuffer,MAXLINE+1);  
int recv_bytes = recv(connfd,dataBuffer,MAXLINE,0);  
//return dataBuffer;  
if(recv_bytes < 0)  
{  
return -2;  
}

if(memcmp(dataBuffer,msg,len)==0){  
return 1;  
}else{  
return -1;  
}

}

编译方法:

gcc handlersocket.c -fPIC -shared -m32 -o libhandlersocket.so

OK大功告成,下面就可以去写LR脚本加载so文件去调用里面的方法了。

LR脚本:

Action()  
{  
int a,b,i;  
int connfd;  
char *msg;  
char msg1[1024];  
char *ip= “10.131.100.21”;  
int port = 9994;  
lr_load_dll (“/home/fuhaitao/libhandlersocket.so”);  
connfd=opensocket(ip,port);  
msg=”P 1 mem_test sbtest PRIMARY id,k,c,pad\n”;  
msgsend(connfd,msg);

a = cmprecvmsg(connfd,”0\t1\t”,3);  
for(i=1;i<=10000;i++){

lr_start_transaction(“handlersocket”);

// msg=”P 1 mem_test sbtest PRIMARY id,k,c,pad\n”;

// connfd=opensocket(ip,port);

// msgsend(connfd,msg);

// a = cmprecvmsg(connfd,”0\t1\t”,3);  
sprintf(msg1,”1 = 1 %s 1 0\n”,lr_eval_string (“{id}”));

msgsend(connfd,msg1);

b=cmprecvmsg(connfd,”0\t4\t”,3);  
if(b!=1 || a!=1){

lr_end_transaction(“handlersocket”, LR_FAIL);

}else{  
lr_end_transaction(“handlersocket”, LR_PASS);  
}

}  
closesocket(connfd);

return 0;  
}

本文链接:http://blogs.360.cn/post/linux下loadrunner建立socket连接方法.html

-- EOF --

Comments