How to Load Test TCP Protocol Services With JMeter
Learn how to test a simple TCP server that works in the echo mode (in other words, the server responds with the same data that has been sent to it).
Join the DZone community and get the full member experience.
Join For FreeIn TCP protocol services, clients send text or binary messages to the service and receive responses from it. Apache JMeter™’s TCP Sampler and TCP Sampler Config elements load test these types of services.
This blog post explains how to test a simple TCP server that works in the echo mode (the server responds with the same data that has been sent to it). The JAR file and java code of this TCP server can be downloaded from here and launched on your local network. In our JMeter script, we will send data to the server via TCP sampler, get responses from the server and analyze them. Then, we will add a TCP Sampler Config.
Let’s get started.
The TCP Sampler
Add a thread group to a new JMeter test plan: Right click > Add > Threads > Thread Group.
Add the TCP sampler as a child element to the thread group: Right click > Sampler > TCP Sampler.
There are three implementations of the TCP sampler in JMeter: one for exchanging text data and two others for exchanging binary data with the tested service.
Each of the implementations is provided by a certain class, which is a "template" or a group of attributes of an object. Enter the name of the class into the TCPClient class name field of the TCP sampler.
The class names, as they are given in the JMeter documentation, are:
TCPClientImpl
. This is a basic class for implementation of the text messages exchange. Text messages are provided as a constant or as variable strings of different charsets in the Text to send field of the TCP sampler.BinaryTCPClientImpl
. This is a class for the implementation of the exchange of the text messages. Binary messages in the form of the hex encoded constant or variable values are provided in the ‘Text to send’ field of the TCP sampler.LengthPrefixedBinaryTCPClientImpl
. This class is similar to the previous one, but byte data to send is prefixed with the binary length byte.
The Basic Class Implementation
Let’s use the basic implementation of the TCP server in our script.
The TCPclient class name field has the name of the class. In this case, it is TCPClientImpl
. As this is the default class name, it may be left out.
The server name or IP is where the simple TCP server is launched. The Port field is the port the TCP server listens to.
The text to send message contains the text that is sent to the server. To demonstrate that the Text to send field is able to process JMeter variables and functions, I’ve changed the loop count parameter in the thread group to 2 and added the ${__iterationNum()}
function to the TCP sampler text. This function prints out the number of current iteration of the currently executed thread group.
Add a View Results Tree listener to the thread group monitor responses from the TCP server: Right click > Add > Listener > View Results Tree.
Save the script, launch a simple TCP server application with the same port parameter that is configured in the script, and launch the script.
Open the View Results Tree Listener. As was mentioned above, the tested TCP server works in the echo mode but adds an information string with the packet number processed to each request. In the screenshot below, you can see the response of the TCP sampler:
These are all required configuration settings that have to be applied to the TCP sampler. But in some cases, when we have to take into account some specific parameters of the network or tested server, we need to apply additional settings:
- The Connect timeout parameter determines the maximum time in milliseconds the particular TCP sampler waits for the establishment of the connection from the server.
- The Response timeout parameter determines the maximum time the particular TCP sampler waits for the response from the server. If you need to consider the network propagation time or the server response time, you may tune the sampler with these parameters in order to avoid receiving too many timed out samplers.
- The Re-use connection parameter instructs the script to use the same connection for sending data; otherwise, the connection established in the previous session will be used.
- The Close connection parameter instructs the script to close connection and open a new one each time the new data is sent.
- If the Set NoDelay parameter is set, small messages, even those the size of only 1 byte, are sent in a separate packet. Otherwise, if this parameter is cleared, a number of small messages is combined in one packet before sending them.
- The SO_LINGER option can be enabled in the socket to cause the script to block the close the connection call for a number of seconds, specified in this field until all final data is delivered to the destination station.
The Binary Class Implementation
If we need to exchange binary data with TCP server, we need to use BynaryTCPClientImpl class and specify this class name in the TCPclient class name field of the TCP sampler. The binary data is entered into the Text to send field in the hex encoded format, as it’s shown in the screenshot below.
Let’s add an additional TCP sampler that sends binary data to the TCP server. The sampler is shown in the screenshot below:
In the Text to send field, let’s send a sequence of two digits hex numbers that represent a sequence of bytes, and see how the TCP sampler response is represented. The sequence of bytes should end with the value that is less than 20. In this example, the binary data in the hex-encoded format that is sent to the TCP server is 63646f0a.
The View Result Tree listener displays the received data from the TCP sampler in the hex-encoded format without converting it to chars:
The hex encoded data in the response is 5061636b657420333a200a63646f0a. The data that was sent to the TCP server is at the end and underlined. Before it appears the hex encoded sequence, which represents information about packet number — each 2 digits is ACSII code in hex format.
The Length Prefixed Binary Class Implementation
The length prefixed binary TCP client implementation is similar to the binary implementation, with the difference that the number of bytes sent is inserted before each message. JMeter inserts this number automatically before each message that it sends to the TCP server. The TCP server, in turn, calculates the number of bytes in the response it sends to JMeter and inserts this number before the message. This fact should be taken into account.
The TCP Sampler Config
Like the HTTP request defaults config element that defines common HTTP parameters for all HTTP samplers in a script, the TCP Sampler Config element defines common parameters for all TCP samplers that are used in a script.
Add the TCP Sampler Config to the script before the thread group and place common parameters, such as the server name and port number, and remove these parameters from the TCP samplers from before.
The TCP sampler can be used together with all preprocessors, postprocessors and assertion elements to make scripts configurable and provide the response analysis.
Modify the script so that it reads text data from files, adds data to the TCP sampler, extracts some data from the response, and asserts against some values. To do that, add the BeanShell preprocessor that will read data from files and feed them to the TCP sampler.
The added preprocessor is shown on the screenshot below:
The preprocessor code:
import java.io.*;
import org.apache.jmeter.protocol.tcp.sampler.*;
String textToSend = "";
String fline = "";
FileReader fR = new FileReader("${fname}");
BufferedReader bR = new BufferedReader(fR);
while((fline = bR.readLine())!= null){
textToSend = textToSend + fline;
}
sampler.setRequestData(textToSend);
To output the TCP Response packet number to the system log and to assert against the text Packet in each response, add a BeanShell PostProcessor, Regular Expression Extractor elements, and an assertion.
The regular expression extractor, extracts the packet number, using the pattern Packet (.+): and places it to the variable packNum
.
The BeanShell postprocessor prints this variable out to the system log, using function print(${packNum}).
This assertion asserts each response, that they contain string about packet number. The pattern, that is used is Packet \d\d.
As you can see, you can work with the TCP sampler by using JMeter-provided implementations. If you need to use more specific processing algorithms for communications over TCP, you may implement them in your own class. All that you need is to extend your class from an existing class, for example from BinaryTCPClientImpl
class, implement what you need and then insert the name of the created class to the TCP client class name field of the TCP sampler.
Published at DZone with permission of Konsantine Firsanov, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments