Process socket data with a leading length value
Asked Answered
P

1

5

This is a follow-up question about how to process prefixed messages received from a network socket. What I try to do is:

  1. Read the first 4 bytes (which is the $prefix and represents the length of the message)
  2. Check if $prefix has really the size of 4 bytes and if it's an integer
  3. Read the complete $message using the length from $prefix
  4. Check if message has really the size of $prefix bytes

So far I've the following two lines of code:

    $prefix = socket_read($socket, 4, PHP_BINARY_READ); //No 1.
    //No 2: how to do the checks?
    $message = socket_read($socket, $prefix, PHP_BINARY_READ); //No 3.
    //No 4: how to do the checks?

How can I do the mentioned checks?

A little side note: all data sent through the network socket connection is in UTF8, little-endian

Patchy answered 17/3, 2012 at 2:12 Comment(0)
B
5

You can validate the length of the binary string you have received by simply using strlen:

$prefix = socket_read($socket, 4, PHP_BINARY_READ);
if (strlen($prefix) != 4) {
    // not 4 bytes long
}

According to your previous question, this binary string represents a 32-bit long. Unpack it as such (with the same format specifier you use when pack-ing it), then fetch the message and use strlen again to validate the length:

$length = current(unpack('l', $prefix));
$message = socket_read($socket, $length, PHP_BINARY_READ);
if (strlen($message) != $length) {
    // $message not the size of $length
}
Brathwaite answered 18/3, 2012 at 4:30 Comment(2)
Thanks again for your help, really appreciate it. To check if the $prefix is an integer, I have to check the unpacked value in $length (is_int($length)), is that correct?Patchy
@Mike: unpack will return false if $prefix is not of the format specified (a 32-bit signed long, l, in the above example). If unpack returns anything but false, you don't have to check for is_int.Brathwaite

© 2022 - 2024 — McMap. All rights reserved.