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

Community
  • 1
  • 1
Mike
  • 1,992
  • 4
  • 31
  • 42

1 Answers1

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
}
netcoder
  • 66,435
  • 19
  • 125
  • 142
  • 3
    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? – Mike Mar 18 '12 at 20:14
  • 2
    @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`. – netcoder Mar 19 '12 at 02:05