JMeter TCP Sampler doesn't recognize end of stream - sockets

I'm trying to run a simple test with TCP Sampler
When using default TCPClient class, after the response timeout time passes, I receive a correct response from the server, and then Error 500 in sampler results:
Response code: 500 Response message:
org.apache.jmeter.protocol.tcp.sampler.ReadException:
It seems like that JMeter does not recognize end of message characters (the server sends \r\n).
How can I configure JMeter to see the EOM?
I tried to use BinaryTCPClientImpl, and set tcp.BinaryTCPClient.eomByte = 13 in Jmeter.properties, but binaryTCPClient expects HEX data, while I send human readable string, and it still ignores the eomByte...
Any ideas?

Found the problem.
Those server did not sent \r\n in several cases.
Everything started working after the server was fixed.

I came accross the same behaviour and examined the offered responses (sending \r\n at the end of the message in the server side \ setting the eol byte value option in the gui) but it didn't work for me.
My solution: Following this question I found that \0 is the eol character Jmeter expects in TCP sampler. when my server terminates the messages with \0 - the message is receieved in Jmeter.
Some more references: Jmeter documentation (TCPClientImpl chapter - that's where the tcp.eolByte is discussed).
Some option: if the size of the messages is constant, one can examine LengthPrefixedBinaryTCPClientImpl (see this discussion).

Anyone give me a solution for this error. Why I m getting 500 response code why jmeter throwing the read exception and what is the solution for this error if I already received my success response.

TCP Sampler will not return until EOF is received.
Set your own EOF byte value at TCP Sampler.
The server sends a stream at the end of EOF byte value.

Related

Bidirectional communication of Unix sockets

I'm trying to create a server that sets up a Unix socket and listens for clients which send/receive data. I've made a small repository to recreate the problem.
The server runs and it can receive data from the clients that connect, but I can't get the server response to be read from the client without an error on the server.
I have commented out the offending code on the client and server. Uncomment both to recreate the problem.
When the code to respond to the client is uncommented, I get this error on the server:
thread '' panicked at 'called Result::unwrap() on an Err value: Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }', src/main.rs:77:42
MRE Link
Your code calls set_read_timeout to set the timeout on the socket. Its documentation states that on Unix it results in a WouldBlock error in case of timeout, which is precisely what happens to you.
As to why your client times out, the likely reason is that the server calls stream.read_to_string(&mut response), which reads the stream until end-of-file. On the other hand, your client calls write_all() followed by flush(), and (after uncommenting the offending code) attempts to read the response. But the attempt to read the response means that the stream is not closed, so the server will wait for EOF, and you have a deadlock on your hands. Note that none of this is specific to Rust; you would have the exact same issue in C++ or Python.
To fix the issue, you need to use a protocol in your communication. A very simple protocol could consist of first sending the message size (in a fixed format, perhaps 4 bytes in length) and only then the actual message. The code that reads from the stream would do the same: first read the message size and then the message itself. Even better than inventing your own protocol would be to use an existing one, e.g. to exchange messages using serde.

How to send some TCP hex packets in JMeter

I'm working on a test scenario that it's testing a socket server over TCP with JMeter.
My test tree and TCP Sampler looks like this:
I used BinaryTCPClientImpl for 'TCPClient classname'. It worked correctly and sent the hex packet (24240011093583349040005000F6C80D0A) to the server and I received the packet in server side too. After receiving the packet in the server side, it answered and JMeter received the response packet correctly too.
As you can see in the following test result, the TCP Sampler (Login Packet) send 4 times in the right way and responses are true (404000120935833490400040000105490d0a).
The problem is that JMeter waits till the end of Timeout (in my case 2000ms) for each request and when it occurred then go to the next request. I don't want to wait for a timeout, I need a forward scenario, without the wait.
I found the solution according to the following question and it helped me:
Answer link
I just set the End of line(EOL) byte value to 10 that it means return new line in ASCI table.

JMeter TCP Sampler doesn't close the socket after data is sent

I've just recently started using JMeter.
I'm trying to run a TCP sampler on one of my servers.
The TCP sampler is set to all default values, with my IP, port number and text to send.
The server receives the text and responds as expected.
However, once JMeter receives the response it doesn't close the connection; it just waits until I stop the test manually, at which point the server logs show the client has disconnected.
I also have a response assertion which looks for this string:
{"SERVER":[{"End":200}]}\r\n
The Assertion is set to apply to main sample and sub-samples, the response field to test is set to Text Response.
With the pattern matching rules set to Equals I get:
Device Server Sampler
Device Server Response Assertion : Test failed: text expected to equal /
****** received : {"SERVER":[{"End":200}]}[[[
]]]
****** comparison: {"SERVER":[{"End":200}]}[[[\r\n]]]
/
If I set pattern matching to Contains I get:
Device Server Sampler
Which I can only assume at this point is a pass??
But no matter how I try it JMeter never closes the socket, so when I stop the tests myself and View the results in a table the status is marked as Warning, even though the correct amount of bytes have been received, and the data is correct.
JMeter doesn't seem to like \r\n so I've run the same tests removing those from the strings on both sides, but the sockets still remain open until I stop the tests.
Got any ideas what the issue may be?
In the TCP Sampler I needed to set End of line(EOL) byte value to 10, which is the decimal byte value for \n

Ensure Completeness of HTTP Messages

I am currently working on an application that is supposed to get a web page and extract information from its content.
As I learned from my research (or as it seems to me at least), there is no ideal way to determine the end of an HTTP message.
Generally, I found two different ways to do so:
Set O_NONBLOCK flag for the socket and fetch data with recv() in a while loop. Assume that the message is complete and break if it occurs once that there are no bytes in the stream.
Rely on the HTTP Content-Length header and determine the end of the message with it.
Both ways don't seem to be completely safe to me. Solution (1) could possibly break the recv loop before the message was completed. On the other hand, solution (2) requires the Content-Length header to be set correctly.
What's the best way to proceed in this case? Can I always rely on the Content-Length header to be set?
Let me start here:
Can I always rely on the Content-Length header to be set?
No, you can't. Content-Length is an optional header. However, HTTP messages absolutely must feature a way to determine their body length if they are to be RFC-compliant (cf RFC7230, sec. 3.3.3). That being said, get ready to parse on chunked encoding whenever a content length isn't specified.
As for your original problem: Ensuring the completeness of a message is actually something that should be TCP's job. But as there are such complicated things like message pipelining around, it is best to check for two things in practice:
Have all reads from the network buffer been successful?
Is the number of the received bytes identical to the predicted message length?
Oh, and as #MartinJames noted, non-blocking probably isn't the best idea here.
The end of a HTTP response is defined:
By the final (empty) chunk in case Transfer-Encoding chunked is used.
By reaching the given length if a Content-length header is given and no chunked transfer encoding is used.
By the end of the TCP connection if neither chunked transfer encoding is used not Content-length is given.
In the first two cases you have a well defined end so you can verify that the data were fully received. Only in the last case (end of TCP connection) you don't know if the connection was closed before sending all the data. But usually you get either case 1 or case 2.
To make your life easier, you might want to provide
Connection: close
header when making HTTP request - than web-server will close connection after giving you the full page requested and you will not have to deal with chunks.
It is only a viable option if you only are interested in this single page, and will not request additional resources (script files, images, etc) - in latter case this will be a very inefficient solution for both your app and the server.

How is determining body length by closing connection reliable (RFC 2616 4.4.5)

I can't get one thing straight. The RFC 2616 in 4.4.5 states that Message Length can be determined "By the server closing the connection.".
This implies, that it is valid for a server to respond (e.g. returning a large image) with a response, that has no Content-Length in the header, but the client is supposed to keep fetching till the connection is closed and then assume all data has been downloaded.
But how is a client to know for sure that the connection was closed intentionally by the server? A server app could have crashed in the middle of sending the data and the server's OS would most likely send FIN packet to gracefully close the TCP connection with the client.
You are absolutely right, that mechanism is totally unreliable. This is covered in RFC 7230:
Since there is no way to distinguish a successfully completed,
close-delimited message from a partially received message interrupted
by network failure, a server SHOULD generate encoding or
length-delimited messages whenever possible. The close-delimiting
feature exists primarily for backwards compatibility with HTTP/1.0.
Fortunately most of HTTP traffic today are HTTP/1.1, with Content-Length or "Transfer-Encoding" to explicitly define the end of message.
The lesson is that, a message must have it own way of termination; we cannot repurpose the underlying transport layer's EOF as the message's EOF.
On that note, a (well-formed) html document, or a .gif, .avi etc, does define its own termination; we will know if we received an incomplete document. Therefore it is not so much of a problem to transmit it over HTTP/1.0 without Content-Length.
However, for plain text document, javascript, css etc. EOF is used to marked the end of the document, therefore it's problematic over HTTP/1.0.