利用LoadRunner编写socket性能测试脚本

本文涉及的产品
性能测试 PTS,5000VUM额度
简介:

一、概述

  Loadrunner拥有极为丰富的工具箱,供予我们制造出各种奇妙魔法的能力。其中就有此次要讨论的socket套接字操作。

  二、socket概述

  socket是操作系统中I/O系统的网络延伸部分,它扩展了操作系统的基本I/O到网络通信,使进程和机器之间的通信成为可能。如果想完全地理解socket在Loadrunner中如何工作的,熟悉一些关于它的历史会很有帮助。

  当前常用的socket,最早起源于BSD UNIX类的操作系统。在UNIX系统上,比如BSD,把对网络的支持加入操作系统,以一种扩展现有文件描述符(后注)结构的方法来实现的。Socket 可以被看成一个标准的文件描述符。在 UNIX 类的平台上,其中包括open()、read()、write()和close()。很多时间,程序并不需要知道它正在把数据写进一个文件、终端、或是一个TCP连接。

  系统调用被加入并和socket一起工作,而很多现有的系统调用同样能和socket一起工作。因此,一个socket允许您使用标准的操作系统和其他的计算机,以及您自己机器上的不同进程来通信。

  然而,socket的确存在一些不同工作方式。最明显地就是建立socket的方法。很多文件是通过调用open()函数来打开的,但socket是通过调用socket()函数来建立的,并且还需要另外的调用来连接和激活他们。recv()和send()这两个系统调用和read()和write()极为相似。

  Socket是一套建立在TCP/IP协议上的接口不是一个协议,只要底层实现TCP IP协议,都可以用socket进行通信。

  应用层: HTTP FTP SMTP Web

  传输层: 在两个应用程序之间提供了逻辑而不是物理的通信基于流的TCP和基于数据包的UDP

  文件描述符一般是指一个文件或某个类似文件的实体。内核(kernel)利用文件描述符(file descriptor)来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。

  文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。

  三、SOCKET连接过程

  根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。

  服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。

  客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。

  连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

  四、开发原理

  服务器:使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。

  客户端:使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。

  Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP网络编程,必须理解Socket接口。Socket接口设计者最先是将接口放在Unix操作系统里面的。如果了解Unix系统的输入和输出的话,就很容易了解Socket了。网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符。Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。

  五、Loadrunner中socket相关函数浅析

  Loadrunner对于脚本函数有一份帮助文档。利用好此文档,其实对于性能测试所需脚本就已足以。

  当我们打开Create/Edit Scripts,并打开脚本录制页面时,摁下F1便可打开《HP LoadRunner Online Function Reference》。在这帮助文档中找到“键入关键字进行查找”输入框。利用它查找我们所需的socket函数了。

  几乎所有关于socket的函数,都是以lrs开头的。

基本操作函数:

lrs_startup 初始化 WinSock DLL

lrs_create_socket 初始化套接字

lrs_send 在数据报上(UDP)或者向流套接字(TCP)发送数据

lrs_receive 接收来自数据报或流套接字的数据

lrs_disable_socket 禁用套接字操作

lrs_close_socket 关闭打开的套接字

lrs_cleanup 终止 WinSock DLL 的使用,回收相关资源。VuGen 在 Windows 上使用 Windows 套接字协议支持应用程序的录制和回放;而在UNIX 平台上仅支持回放

lrs_accept_connection 接受侦听套接字连接

lrs_close_socket 关闭打开的套接字

lrs_create_socket 初始化套接字

lrs_disable_socket 禁用套接字操作

lrs_exclude_socket 重播期间排除套接字

lrs_get_socket_attrib 获取套接字属性

lrs_get_socket_handler 获取指定套接字的套接字处理程序

lrs_length_receive 接收来自指定长度的缓冲区的数据

lrs_receive 接收来自套接字的数据

lrs_receive_ex 接收来自数据报或流套接字的数据(具有特定长度)

lrs_send 将数据发送到数据报上或流套接字中

lrs_set_receive_option 设置套接字接收选项

lrs_set_socket_handler 设置特定套接字的套接字处理程序

lrs_set_socket_options 设置套接字选项

  缓冲区函数:

lrs_free_buffer 释放分配给缓冲区的内存

lrs_get_buffer_by_name 从数据文件中获取缓冲区及其大小

lrs_get_last_received_buffer 获取套接字上接收到的最后的缓冲区及其大小

lrs_get_last_received_buffer_size 获取套接字上接收到的最后一个缓冲区的大小

lrs_get_received_buffer 获取最后接收到的缓冲区或其一部分

lrs_get_static_buffer 获取静态缓冲区或其一部分

lrs_get_user_buffer 获取套接字的用户数据的内容

lrs_get_user_buffer_size 获取套接字的用户数据的大小

lrs_set_send_buffer 指定要在套接字上发送的缓冲区

  环境函数:

  lrs_cleanup 终止Windows套接字 DLL 的使用

  lrs_startup 初始化 Windows 套接字 DLL

  关联语句函数:

  lrs_save_param 将静态或接收到的缓冲区(或缓冲区部分)保存到参数中

  lrs_save_param_ex 将用户、静态或接收到的缓冲区(或缓冲区部分)保存到参数中

  lrs_save_searched_string 在静态或接收到的缓冲区中搜索出现的字符串,将出现字符串的缓冲区部分保存到参数中

  转换函数

  lrs_ascii_to_ebcdic 将缓冲区数据从 ASCII 格式转换成 EBCDIC 格式

  lrs_decimal_to_hex_string 将十进制整数转换为十六进制字符串

  lrs_ebcdic_to_ascii 将缓冲区数据从 EBCDIC 格式转换成ASCII 格式

  lrs_hex_string_to_int 将十六进制字符串转换为整数

  超时函数:(这一堆函数,是可以对同一个socket生效的)

  lrs_set_accept_timeout 为接受套接字设置超时

  lrs_set_connect_timeout 为连接到套接字设置超时

  lrs_set_recv_timeout 执行lrs_receive命令后,等待服务器返回消息的超时时间,即服务器的响应时间。

  lrs_set_recv_timeout2 创建连接成功,接收到服务器返回的消息后,获取匹配消息的超时时间。lrs_receive接收到数据后,会和预期的数据长度进行比较,如果长度不匹配,它将重新从套接字上读取数据,直到超时为止。

  lrs_set_send_timeout 为发送套接字数据设置超时

  六、实战讲解

  在此只做简单的知识普及,便于快速上手编写socket测试脚本。简述创建连接,收发协议,关闭连接的过程。

  初始化

//存放通信返回报文

char * ActualBuffer="";

//存放返回报文长度,切记附初值

int numberOfResponse = -1;

//链接是否创建成功,判断值

int rc = 0;

//返回报文是否成功,判断值

int msgOk=-1;

//存放返回报文

char * position="";

//返回报文是否成功标识

char * passMsg="succee";

 服务器监听

//--------------创建连接-----------------

rc= lrs_create_socket("socket0", "TCP", "LocalHost=0", "RemoteHost=<RemoteHost>", LrsLastArg);

if (rc==0){

//判断连接是否创建成功

lr_output_message("Socket was successfully created ");

}

else{

lr_output_message("An error occurred while creating the socket, Error Code: %d", rc);

}

//--------------创建连接-----------------

  收发协议

lrs_send("socket0", "buf0", LrsLastArg);

//往“socket0”发送"buf0"

lrs_set_receive_option(EndMarker, BinaryStringTerminator, "</html>");

//设置接收协议包选项,注"</html>"以实际定义协议为准,如果不设置次项。执行到lrs_receive的时候,log里面打印Waiting for writable socket 10

//secs, 0 usecs,都需要等待10秒钟。是这样的,因为你在data.ws中定义了recv buffer的长度,例如你定义为100,但是socket上的返回buffer长度不

//是100,这时候,loadrunner会尝试再次去读取,直到读到长度为100的buffer才算成功。

lrs_receive("socket0", "buf1","Flags=MSG_PEEK ", LrsLastArg);

//将“socket0”中返回的数据存放到“buf1”中

  参数配置

  可能细心的同学已经发现了,buf0与buf1是从哪里来的。其实这俩兄弟是在data.ws中被定义的,如下所示:

  ;WSRData 2 1

  send buf0 5120

  "<参数化>"

  recv buf1 1024

  -1

  5120:此数值为socket协议传输内容长度,切记严格输入正确长度值。

  "<参数化>":为buf0所传输内容。相对于loadrunner的http协议参数用{}来说,socket协议参数化采用<>作为定义符。

  接收参数判断

  在做了接收之后,我们需要提取“buf1”中的某些关键字符作为通信成功标识。

//获取套接字上接收到的最后的缓冲区及其大小

lrs_get_last_received_buffer("socket0",&ActualBuffer,&numberOfResponse);

//查询返回报文是否成功

position = (char *)strstr(ActualBuffer, passMsg);

// strstr has returned the address. Now calculate * the offset from the beginning of str

msgOk = (int)(position - ActualBuffer + 1);

if(msgOk>0){

lr_end_transaction("核心对私维护", LR_PASS);

lr_output_message("本次交易:%s",ActualBuffer);

}

else{

lr_end_transaction("核心对私维护", LR_FAIL);

lr_error_message("本次交易:%s",ActualBuffer);

}

关闭连接

//--------------断开socket--------------

lrs_disable_socket("socket0", DISABLE_SEND_RECV);

//--------------关闭socket--------------

lrs_close_socket("socket0");

  六、总结

  简要描述了利用Loadrunner编写socket性能测试脚本的过程,如有错漏,请予以指正。

注:

 

strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。

函数原型:extern char *strstr(char *str1, const char *str2);

语法:

* strstr(str1,str2)

str1: 被查找目标 string expression to search.

str2: 要查找对象 The string expression to find.

返回值:若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL。

例子:

char str[]="1234xyz";

char *str1=strstr(str,"34");

cout << str1 << endl;

显示的是: 34xyz;显示匹配后全部数据;










本文转自 知止内明 51CTO博客,原文链接:http://blog.51cto.com/357712148/1709652,如需转载请自行联系原作者
相关实践学习
通过性能测试PTS对云服务器ECS进行规格选择与性能压测
本文为您介绍如何利用性能测试PTS对云服务器ECS进行规格选择与性能压测。
目录
相关文章
|
1月前
|
Java Shell
「sh脚步模版自取」测试线排查的三个脚本:启动、停止、重启、日志保存
「sh脚步模版自取」测试线排查的三个脚本:启动、停止、重启、日志保存
37 1
|
10天前
|
存储 监控 测试技术
测试脚本编写和维护的最佳实践有哪些?
测试脚本编写和维护的最佳实践有哪些?
|
3月前
|
测试技术 数据库
自动化测试的救赎:揭秘代码复用的艺术,让测试脚本涅槃重生!
【8月更文挑战第21天】自动化测试对提升软件质量和开发效率至关重要,但其维护成本随项目规模增长而上升。采用代码复用策略能显著减轻这一负担。本文概述了自动化测试中实现代码复用的方法,包括抽象与封装、模块化、参数化、继承及利用测试框架等,以减少重复劳动、提高代码质量与开发速度,并简化维护流程。掌握这些策略将助力构建高效、可维护的自动化测试体系。
63 5
|
10天前
|
存储 监控 前端开发
如何确保测试脚本的稳定性和可靠性?
确保测试脚本的稳定性和可靠性是保证性能测试结果准确有效的关键
|
10天前
|
监控 网络协议 Java
一些适合性能测试脚本编写和维护的工具
一些适合性能测试脚本编写和维护的工具
|
10天前
|
测试技术 数据库连接 数据库
测试脚本的编写和维护对性能测试结果有何影响?
测试脚本的编写和维护对性能测试结果有着至关重要的影响,
18 1
|
1月前
|
Java 流计算
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
37 1
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
|
25天前
|
JSON 测试技术 持续交付
自动化测试与脚本编写:Python实践指南
自动化测试与脚本编写:Python实践指南
27 1
|
2月前
|
安全 JavaScript 前端开发
自动化测试的魔法:如何用Python编写你的第一个测试脚本
【8月更文挑战第41天】在软件的世界里,质量是王道。而自动化测试,就像是维护这个王国的骑士,确保我们的软件产品坚不可摧。本文将引导你进入自动化测试的奇妙世界,教你如何使用Python这把强大的魔法杖,编写出能够守护你代码安全的第一道防护咒语。让我们一起开启这场魔法之旅吧!
|
3月前
|
网络协议 测试技术 网络安全
Python进行Socket接口测试的实现
在现代软件开发中,网络通信是不可或缺的一部分。无论是传输数据、获取信息还是实现实时通讯,都离不开可靠的网络连接和有效的数据交换机制。而在网络编程的基础中,Socket(套接字)技术扮演了重要角色。 Socket 允许计算机上的程序通过网络进行通信,它是网络通信的基础。Python 提供了强大且易于使用的 socket 模块,使开发者能够轻松地创建客户端和服务器应用,实现数据传输和交互。 本文将深入探讨如何利用 Python 编程语言来进行 Socket 接口测试。我们将从基础概念开始介绍,逐步引导大家掌握创建、测试和优化 socket 接口的关键技能。希望本文可以给大家的工作带来一些帮助~