2

I need some help on identifying the length of the response using the the first byte(s) of the message.

Currently using JMeter to send some TCP request but unfortunately it is not able to determine the end of the message, so it hangs.

The communication protocol is Google Protobufs (protocol buffers) and does not have an indicator to determine the end of message.

Below is what Jmeter has. I would appreciate if someone can tell me how I can build on top of this so I can measure the length of the message using the first bytes of the response.

JMETER - Read method.

public String read(InputStream is) throws ReadException {
    ByteArrayOutputStream w = new ByteArrayOutputStream();
    try {
        byte[] buffer = new byte[127];
        int x = 0;
        while ((x = is.read(buffer)) > -1) {
            w.write(buffer, 0, x);
            if (useEolByte && (buffer[x - 1] == eolByte)) {
                break;
            }
                }
        IOUtils.closeQuietly(w); // For completeness
        final String hexString = JOrphanUtils.baToHexString(w.toByteArray());
        if(log.isDebugEnabled()) {
            log.debug("Read: " + w.size() + "\n" + hexString);
        }
        return hexString;
    } catch (IOException e) {
            throw new ReadException("", e, JOrphanUtils.baToHexString(w.toByteArray()));
    }
}
UBIK LOAD PACK
  • 33,980
  • 5
  • 71
  • 116
tosi
  • 1,873
  • 2
  • 18
  • 38

3 Answers3

1

First read this:

Then if you are sending some custom character indicating end of line, in protocole then try uncommenting in jmeter.properties:

  • tcp.eolByte=

If you are sending length at the start of message, then use:

If this is not enough for you, then code a new ClientImpl extending AbstractTCPClient.

Regards

Philippe M

Community
  • 1
  • 1
UBIK LOAD PACK
  • 33,980
  • 5
  • 71
  • 116
1

As in this case, length is contained in the first byte(s) of the response, the solution was to write a custom LengthPrefixedBinaryTCPClientImpl inspired from

with the following read method:

public String read(InputStream is) throws ReadException {
    ByteArrayOutputStream w = new ByteArrayOutputStream();
    try {
        int mLen = readUnsignedInt(is);
        for (int i = 0; i < mLen ; i++) {
            int nByte= is.read();
            w.write(nByte);
        }  // carry on

....

determine the length of the message. (bear in mind little-endian and big-endian)

public static int readUnsignedInt(InputStream in) throws IOException {
    int b = in.read();
    int i = b & 0x7F;
    for (int shift = 7; (b & 0x80) != 0; shift += 7) {
        b = in.read();
        i |= (b & 0x7FL) << shift;
    }
    return i;
}

Then package the class as a JAR and put it in :

  • /lib/ext
UBIK LOAD PACK
  • 33,980
  • 5
  • 71
  • 116
tosi
  • 1,873
  • 2
  • 18
  • 38
  • I edited your answer so you don't modify JMeter base code but instead create a new class. I am not 100% sure about your readUnsignedInt method. – UBIK LOAD PACK Sep 17 '12 at 20:27
  • Thanks Philippe, Yes i did not modify any JMeter classes I created a new one. – tosi Sep 18 '12 at 09:39
0

It's not possible to get the size of the contents in input stream without reading it.

alexp
  • 787
  • 5
  • 26