Loadrunner 进行SOCKET并发测试遇到问题

简介:
我对一个协议进行了封装,希望能在loadrunner下调用。结果调用收包函数的时候老是压不上去。
函数大致内容如下

extern "C" LRDLLTEST_API int receive_version_data(int sockfd)
{
char* receiveBuf = (char *)malloc(1024);
memset(receiveBuf,0,1024);
int n = recv(sockfd,(char *)receiveBuf,1024,0);
free(receiveBuf);
return n;
}
经过反复的验证,网上查资料终于发现
int n = recv(sockfd,(char *)receiveBuf,1024,0);
语句有问题
经修改如下:
int n = recv(sockfd,(char *)receiveBuf,1024,MSG_PEEK);
参阅资料如下:
旦,我们建立好了tcp连接之后,我们就可以把得到的fd当作文件描述符来使用。
由此网络程序里最基本的函数就是read和write函数了。
ssize_t write(int fd, const void*buf,size_t nbytes);
write函数将buf中的nbytes字节内容写入文件描述符fd.成功时返回写的字节数.失败时返回-1. 并设置errno变量. 在网络程序中,当我们向套接字文件描述符写时有两可能. 
1)write的返回值大于0,表示写了部分或者是全部的数据. 这样我们用一个while循环来不停的写入,但是循环过程中的buf参数和nbyte参数得由我们来更新。也就是说,网络写函数是不负责将全部数据写完之后在返回的。
2)返回的值小于0,此时出现了错误.我们要根据错误类型来处理. 

如果错误为EINTR表示在写的时候出现了中断错误. 
如果为EPIPE表示网络连接出现了问题(对方已经关闭了连接). 
为了处理以上的情况,我们自己编写一个写函数来处理这几种情况. 


int my_write(int fd,void *buffer,int length) 

int bytes_left; 
int written_bytes; 
char *ptr; 

ptr=buffer; 
bytes_left=length; 
while(bytes_left>0) 

/* 开始写*/ 
written_bytes=write(fd,ptr,bytes_left); 
if(written_bytes<=0) /* 出错了*/ 

if(errno==EINTR) /* 中断错误 我们继续写*/ 
written_bytes=0; 
else /* 其他错误 没有办法,只好撤退了*/ 
return(-1); 

bytes_left-=written_bytes; 
ptr+=written_bytes; /* 从剩下的地方继续写 */ 

return(0); 


读函数read 
ssize_t read(int fd,void *buf,size_t nbyte) 
read函数是负责从fd中读取内容.当读成功 时,read返回实际所读的字节数,如果返回的值是0 表示已经读到文件的结束了,小于0表示出现了错误.如果错误为EINTR说明读是由中断引起 的, 如果是ECONNREST表示网络连接出了问题. 和上面一样,我们也写一个自己的读函数. 

int my_read(int fd,void *buffer,int length) 

int bytes_left; 
int bytes_read; 
char *ptr; 

bytes_left=length; 
while(bytes_left>0) 

bytes_read=read(fd,ptr,bytes_read); 
if(bytes_read<0) 

if(errno==EINTR) 
bytes_read=0; 
else 
return(-1); 

else if(bytes_read==0) 
break; 
bytes_left-=bytes_read; 
ptr+=bytes_read; 

return(length-bytes_left); 
}

数据的传递 
有了上面的两个函数,我们就可以向客户端或者是服务端传递数据了.比如我们要传递一个结构.可以使用如下方式 

/* 客户端向服务端写 */ 

struct my_struct my_struct_client; 
write(fd,(void *)&my_struct_client,sizeof(struct my_struct); 

/* 服务端的读*/ 
char buffer[sizeof(struct my_struct)]; 
struct *my_struct_server; 
read(fd,(void *)buffer,sizeof(struct my_struct)); 
my_struct_server=(struct my_struct *)buffer; 

在网络上传递数据时我们一般都是把数据转化为char类型的数据传递.接收的时候也是一样的 注意的是我们没有必要在网络上传递指针(因为传递指针是没有任何意义的,我们必须传递指针所指向的内容)


6.1 recv和send 
recv和send函数提供了和read和write差不多的功能.不过它们提供 了第四个参数来控制读写操作. 

int recv(int sockfd,void *buf,int len,int flags) 
int send(int sockfd,void *buf,int len,int flags) 

前面的三个参数和read,write一样,第四个参数可以是0或者是以下的组合 
_______________________________________________________________ 
| MSG_DONTROUTE | 不查找表 | 
| MSG_OOB | 接受或者发送带外数据 | 
| MSG_PEEK | 查看数据,并不从系统缓冲区移走数据 | 
| MSG_WAITALL | 等待所有数据 | 
|--------------------------------------------------------------| 

MSG_DONTROUTE:是send函数使用的标志.这个标志告诉IP.目的主机在本地网络上面,没有必要查找表.这个标志一般用网络诊断和路由程序里面. 
MSG_OOB:表示可以接收和发送带外的数据.关于带外数据我们以后会解释的. 

MSG_PEEK:是recv函数的使用标志, 表示只是从系统缓冲区中读取内容,而不清除系统缓冲区的内容.这样下次读的时候,仍然是一样的内容.一般在有多个进程读写数据时可以使用这个标志. 

MSG_WAITALL 是recv函数的使用标志,表示等到所有的信息到达时才返回.使用这个标志的时候recv回一直阻塞,直到指定的条件满足,或者 是发生了错误. 1)当读到了指定的字节时,函数正常返回.返回值等于len 2)当读到了文件的结尾时,函数正常返回.返回值小于len 3)当操作发生错误时,返回-1,且设置错误为相应的错误号(errno)
MSG_NOSIGNAL is a flag used by send() in some implementations of the Berkeley sockets  API.
This flag requests that the implementation does not to send a  SIGPIPE signal on errors on stream oriented sockets when the other end breaks the connection. The  EPIPE error is still returned as normal.
Though it is in some Berkely sockets APIs (notably Linux) it does not exist in what some refer to as the reference implementation,  FreeBSD, which instead uses a socket option  SO_NOSIGPIPE?. 对于服务器端,我们可以使用这个标志。目的是不让其发送SIG_PIPE信号,导致程序退出。
如果flags为0,则和read,write一样的操作.还有其它的几个选项,不过我们实际上用的很少,可以查看 Linux Programmer's Manual得到详细解释.


本文转自elbertchen 51CTO博客,原文链接:http://blog.51cto.com/linkyou/750669,如需转载请自行联系原作者c
相关文章
|
9月前
|
JSON 测试技术 网络安全
Apifox工具让我的 Socket.IO 测试效率翻倍
用了 Apifox 测试 Socket.IO 后,我整个人都升级了!不仅操作简单到令人发指,功能还贼全面,真的是 提升开发效率的神器 !
|
9月前
|
监控 API 开发工具
Socket.IO介绍,以及怎么连接测试Socket.IO接口?
Socket.IO 是一个用于浏览器和服务器间实时双向通信的库,支持低延迟消息传递、跨平台运行及自动重连。文章介绍了其特点与调试需求,并详细说明如何使用 Apifox 工具创建、连接、发送/接收 Socket.IO 事件,以及团队协作和调试技巧。掌握这些技能可提升实时应用开发效率与质量。
|
Java 流计算
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
187 1
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
|
网络协议 测试技术 网络安全
Python进行Socket接口测试的实现
在现代软件开发中,网络通信是不可或缺的一部分。无论是传输数据、获取信息还是实现实时通讯,都离不开可靠的网络连接和有效的数据交换机制。而在网络编程的基础中,Socket(套接字)技术扮演了重要角色。 Socket 允许计算机上的程序通过网络进行通信,它是网络通信的基础。Python 提供了强大且易于使用的 socket 模块,使开发者能够轻松地创建客户端和服务器应用,实现数据传输和交互。 本文将深入探讨如何利用 Python 编程语言来进行 Socket 接口测试。我们将从基础概念开始介绍,逐步引导大家掌握创建、测试和优化 socket 接口的关键技能。希望本文可以给大家的工作带来一些帮助~
|
网络协议 测试技术 网络安全
Python进行Socket接口测试的实现
在现代软件开发中,网络通信是不可或缺的一部分。无论是传输数据、获取信息还是实现实时通讯,都离不开可靠的网络连接和有效的数据交换机制。而在网络编程的基础中,Socket(套接字)技术扮演了重要角色。 Socket 允许计算机上的程序通过网络进行通信,它是网络通信的基础。Python 提供了强大且易于使用的 socket 模块,使开发者能够轻松地创建客户端和服务器应用,实现数据传输和交互。 本文将深入探讨如何利用 Python 编程语言来进行 Socket 接口测试。我们将从基础概念开始介绍,逐步引导大家掌握创建、测试和优化 socket 接口的关键技能。希望本文可以给大家的工作带来一些帮助~
|
存储 测试技术
Loadrunner 脚本开发-利用Loadrunner生成Web service测试脚本
Loadrunner 脚本开发-利用Loadrunner生成Web service测试脚本
242 0
Loadrunner 脚本开发-利用Loadrunner生成Web service测试脚本
|
Python
Socket接口测试
Socket接口测试
411 0
|
Java 测试技术 Android开发
Loadrunner脚本开发-基于HTTP协议的流媒体视频在线播放服务器性能测试
Loadrunner脚本开发-基于HTTP协议的流媒体视频在线播放服务器性能测试
401 0
|
XML 存储 测试技术
Loadrunner 脚本开发-soap_request函数介绍及WebService接口测试
Loadrunner 脚本开发-soap_request函数介绍及WebService接口测试
307 0
|
JSON 测试技术 数据格式
Loadrunner 脚本开发-利用web_custom_request函数进行接口测试
Loadrunner 脚本开发-利用web_custom_request函数进行接口测试
351 0