Loadrunner's functions on sockets and an introduction to sockets

I. Overview

        Loadrunner has a very rich toolbox for us to create all kinds of wonderful magic. Among them is the socket operation to be discussed this time.


Two, socket overview

        Socket is the network extension part of the I/O system in the operating system. It extends the basic I/O of the operating system to the network communication, making the communication between the process and the machine possible. If you want to fully understand how sockets work in Loadrunner, it's helpful to be familiar with some of its history.

        Currently commonly used sockets originated from BSD UNIX operating systems. On UNIX systems, such as BSD, the support for the network is added to the operating system, which is implemented in a way to extend the structure of the existing file descriptor (note below). Socket can be regarded as a standard file descriptor. On UNIX-like platforms, these include open(), read(), write() and close(). Many times, the program does not need to know that it is writing data into a file, terminal, or a TCP connection.

        System calls are added and work with sockets, and many existing system calls can also work with sockets. Therefore, a socket allows you to use a standard operating system to communicate with other computers, as well as different processes on your own machine.

        However, sockets do have some different ways of working. The most obvious is the way to establish a socket. Many files are opened by calling the open() function, but the socket is established by calling the socket() function, and additional calls are needed to connect and activate them. The two system calls recv() and send() are very similar to read() and write().

        Socket is a set of interfaces built on the TCP/IP protocol, not a protocol, as long as the bottom layer implements the TCP IP protocol, sockets can be used for communication.

        Application layer: HTTP FTP SMTP Web

        Transport layer: Provides logical rather than physical communication between two applications based on TCP flow and packet based UDP

        A file descriptor generally refers to a file or a file-like entity. The kernel uses file descriptors to access files. The file descriptor is a non-negative integer. When opening an existing file or creating a new file, the kernel returns a file descriptor. Reading and writing files also need to use file descriptors to specify the files to be read and written.

        The file descriptor is a non-negative integer in form. In fact, it is an index value that points to the record table of files opened by the process maintained by the kernel for each process. When the program opens an existing file or creates a new file, the kernel returns a file descriptor to the process. In programming, some programming involving the bottom layer is often developed around file descriptors. However, the concept of file descriptors is often only applicable to operating systems such as UNIX and Linux.


Three, SOCKET connection process

        According to the way the connection is started and the destination of the local socket to be connected, the connection process between the sockets can be divided into three steps: server monitoring, client request, and connection confirmation.

        Server monitoring: The server-side socket does not locate the specific client socket, but is in a state of waiting for connection, real-time monitoring of the network status.

        Client request: refers to the connection request made by the client's socket, and the target of the connection is the server-side socket. For this reason, the socket of the client must first describe the socket of the server it wants to connect to, point out the address and port number of the server-side socket, and then make a connection request to the server-side socket.

        Connection confirmation: refers to when the server-side socket monitors or receives the connection request of the client-side socket, it responds to the request of the client-side socket, establishes a new thread, and connects the server-side socket The description is sent to the client. Once the client confirms the description, the connection is established. The server socket continues to be in the listening state and continues to receive connection requests from other client sockets.


Four, development principle

        Server : Use ServerSocket to monitor the specified port, the port can be specified at will (because ports below 1024 are usually reserved ports, and cannot be used at will in some operating systems, it is recommended to use ports greater than 1024), waiting for client connection requests, client connections After that, the session is generated; after the session is completed, the connection is closed.

        Client : Use Socket to send a connection request to a certain port of a server on the network. Once the connection is successful, open the session; after the session is completed, close the Socket. The client does not need to specify an open port, usually a port above 1024 is allocated temporarily and dynamically.

        The Socket interface is the API of the TCP/IP network. The Socket interface defines many functions or routines. Programmers can use them to develop applications on the TCP/IP network. To learn TCP/IP network programming on the Internet, you must understand the Socket interface. The designer of the Socket interface first put the interface in the Unix operating system. If you understand the input and output of the Unix system, it is easy to understand Socket. Network Socket data transmission is a special I/O, and Socket is also a file descriptor. Socket also has a function similar to opening a file called Socket(), which returns an integer Socket descriptor, and subsequent operations such as connection establishment and data transmission are implemented through the Socket.


5. Analysis of socket related functions in Loadrunner

        Loadrunner has a help document for script functions. Making good use of this document is actually sufficient for the scripts required for performance testing.

        When we open Create/Edit Scripts and open the script recording page, press F1 to open the "HP LoadRunner Online Function Reference". In this help document, find the input box of "Type a keyword to find". Use it to find the socket function we need.

        Almost all socket functions start with lrs.

        Basic operation function:

lrs_startup initialize WinSock DLL

lrs_create_socket initialize socket

lrs_send sends data on the datagram (UDP) or to the stream socket (TCP)

lrs_receive receives data from datagrams or stream sockets

lrs_disable_socket Disable socket operation

lrs_close_socket closes the open socket

lrs_cleanup terminates the use of WinSock DLL and reclaims related resources. VuGen uses the Windows socket protocol on Windows to support recording and playback of applications; on the UNIX platform, only playback is supported

lrs_accept_connection accept listening socket connection

lrs_close_socket closes the open socket

lrs_create_socket initialize socket

lrs_disable_socket Disable socket operation

lrs_exclude_socket exclude socket during replay

lrs_get_socket_attrib Get socket attributes

lrs_get_socket_handler gets the socket handler of the specified socket

lrs_length_receive receives data from a buffer of a specified length

lrs_receive receives data from the socket

lrs_receive_ex receives data (with a specific length) from a datagram or stream socket

lrs_send sends data to the datagram or stream socket

lrs_set_receive_option set socket receive option

lrs_set_socket_handler sets the socket handler for a specific socket

lrs_set_socket_options set socket options

  Buffer function:

lrs_free_buffer releases the memory allocated to the buffer

lrs_get_buffer_by_name gets the buffer and its size from the data file

lrs_get_last_received_buffer gets the last buffer received on the socket and its size

lrs_get_last_received_buffer_size gets the size of the last buffer received on the socket

lrs_get_received_buffer gets the last received buffer or part of it

lrs_get_static_buffer get static buffer or part of it

lrs_get_user_buffer gets the contents of the user data of the socket

lrs_get_user_buffer_size gets the size of the user data of the socket

lrs_set_send_buffer specifies the buffer to be sent on the socket

  Environmental function:

lrs_cleanup terminates the use of Windows socket DLL

lrs_startup initializes the Windows socket DLL

  Associated statement function:

lrs_save_param save the static or received buffer (or buffer part) to the parameter

lrs_save_param_ex save the user, static or received buffer (or buffer part) to the parameter

lrs_save_searched_string Search for the string that appears in the static or received buffer, and save the buffer part of the string that appears in the parameter

  Conversion function:

lrs_ascii_to_ebcdic converts buffer data from ASCII format to EBCDIC format

lrs_decimal_to_hex_string converts a decimal integer to a hexadecimal string

lrs_ebcdic_to_ascii converts buffer data from EBCDIC format to ASCII format

lrs_hex_string_to_int converts a hexadecimal string to an integer

  Timeout function: (This bunch of functions can be effective for the same socket)

lrs_set_accept_timeout sets a timeout for the accept socket

lrs_set_connect_timeout sets a timeout for connecting to the socket

lrs_set_recv_timeout After executing the lrs_receive command, the timeout period for waiting for the server to return a message, that is, the server's response time.

lrs_set_recv_timeout2 The connection is successfully established, and the timeout period for obtaining the matching message after receiving the message returned by the server. After lrs_receive receives the data, it will compare it with the expected data length. If the length does not match, it will read the data from the socket again until it times out.

lrs_set_send_timeout sets a timeout for sending socket data        


Six, actual combat explanation

        Only simple knowledge popularization is done here, so that it is easy to quickly get started writing socket test scripts. Briefly describe the process of creating a connection, sending and receiving protocols, and closing the connection.

  • initialization

//Store communication return message

 char * ActualBuffer="";

//Store the length of the returned message, remember to attach the initial value

 int numberOfResponse = -1;

// Whether the link is created successfully, judge the value

 int rc = 0;

//Return whether the message is successful, judgment value

    int msgOk=-1;

//Store return message

    char * position="";

//Identify whether the returned message is successful

 char * passMsg="succee";


  • Server listening

 //--------------Create connection-----------------

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

 if (rc==0){

//Determine whether the connection is successfully created

  lr_output_message("Socket was successfully created ");

}

 else{

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

}

 //--------------Create connection-----------------

 


  • Send and receive protocol

lr_start_transaction("Transaction");

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

  //Send "buf0" to "socket0"

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

  //Set the receiving protocol package option, the note "</html>" is subject to the actual defined protocol, if you do not set the second item. When the execution reaches lrs_receive, the log will print Waiting for writable socket 10 

  //secs, 0 usecs, all need to wait 10 seconds. This is the case, because you define the recv buffer length in data.ws, for example, you define it as 100, but the return buffer length on the socket is not

  //It is 100. At this time, loadrunner will try to read again until it reads a buffer with a length of 100.

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

//Store the data returned in "socket0" into "buf1"

 

  • Receive parameter judgment

        After receiving, we need to extract some key characters in "buf1" as the communication success indicator.

    //Get the last buffer received on the socket and its size

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

   //Check whether the returned message is successful

    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("This transaction: %s",ActualBuffer);

 }

 else{

  lr_end_transaction("事务", LR_FAIL);

  lr_error_message("This transaction: %s",ActualBuffer);

 }


  • Close the connection

 //--------------Disconnect socket--------------

 lrs_disable_socket("socket0", DISABLE_SEND_RECV);

 //--------------Close the socket--------------

 lrs_close_socket("socket0");

  • Parameter configuration

        Perhaps the attentive classmates have found out where buf0 and buf1 come from. In fact, these two brothers are defined in data.ws, as shown below:

;WSRData 2 1

send buf0 5120

"<parameterization>"

recv buf1 1024

-1

        5120: This value is the length of the content transmitted by the socket protocol. Remember to enter the correct length value strictly.

        "<Parameterization>": The content transmitted by buf0. Compared with loadrunner's http protocol parameter using {}, socket protocol parameterization uses <> as the delimiter.

Guess you like

Origin blog.csdn.net/u014179640/article/details/92851090