PHP - get package length

I am currently dealing with sockets and packages in PHP and don't know where to start with getting the length of the packet. I tried this from the GitHub repo (I don’t remember which one):

    private function get_packet_length($socket) {
        $a = 0;
        $b = 0;
        while(true) {
            $c = socket_read($socket, 1);
            if (!$c) {
                return 0;
            }
            $c = ord($c);
            $a |= ($c & 0x7F) << $b++ * 7;
            if ($b > 5) {
                return false;
            }
            if (($c & 0x80) != 128) {
                break;
            }
        }
        return $a;
    }

Does anyone know why this will not work? I get it int(1).

EDIT

private function get_packet_length($socket) {
        $a = 0;
        $b = 0;
        while(true) {
            $c = socket_read($socket, 10240);
            if (!$c) {
                return 0;
            }
            $c = ord($c);
            $a .= strlen($c);
            if ($b > 5) {
                return false;
            }
            if (($c & 0x80) != 128) {
                break;
            }
        }
        return $a;
    }

Output: string(2) "01"

+4
source share
3 answers

, C . , . (UDP , , UDP, , .) , , , - , .

, , ? , , . , , , , , .

, PHP ioctl(2) raw socket FD. - ioctl(sock, FIONREAD, &n) PHP-land, . ( , , , fopen fsockopen, , .) , .

, :

, , , , -. socket_select ; , , , socket_read. (, 10 ), .

, , , .

, , . , , , . , , .

, . , , , , . , pack 32- . , 4 . 4 , unpack , , .

<?php
$payload = "Have a nice day!\n";
$len = strlen($payload) + 1; // + 1 for terminating NUL byte
$packet = pack("Na", $len, $payload);
socket_send($sock, $packet, $len + 4); // + 4 is length 
...

<?php
$r = socket_read($sock, 4);
$la = unpack("N", $r);

// Because we don't know how much to read until we get the first 4 bytes.
// Obviously this is a DoS vector for someone to hold the connection open,
// so you will likely want to use socket_select to get that first bit of
// data. That an exercise for you.
socket_set_nonblock($sock);
$len = $la[1];
$time = 0;
$payload = "";
while ($len > 0 && $time < 10) { 
    $data = socket_read($sock, $la[1]);
    $tlen = strlen($data);
    $payload .= $data;
    $len -= $tlen;
    if ($len == 0) { 
        break;
    }
    sleep(1); // Feel free to usleep.
    $time++;
 }

N.B. , , / , , . .

. HTTP, , Content-Length .

, , . , , . , .

, . (, ZeroMQ push- Apple - .) , , - , ?

private function get_packet_length($socket) {
    $a = 0;
    $b = 0;
    while(true) {
        /* Read next single byte off of the socket */
        $c = socket_read($socket, 1);
        if (!$c) {
            return 0;
        }

        /* Use integer value of the byte instead of the character value */
        $c = ord($c);

        /*
         * Get the first 7 bits of $c. Since $c represents an integer value
         * of a single byte, its maximum range is [0, 2^8). When we use only
         * 7 bits, the range is constrained to [0, 2^7), or 0 - 127. This
         * means we are using the 8th bit as a flag of some kind -- more on
         * this momentarily.
         *
         * The next bit executed is ($b++ * 7), since multiplication has
         * higher precedence than a left shift. On the first iteration, we
         * shift by 0 bits, the second we shift 7 bits, the third we shift
         * 14 bits, etc. This means that we're incrementally building an
         * integer value byte by byte. We'll take a look at how this works
         * out on real byte sequences in a sec.
         */
        $a |= ($c & 0x7F) << $b++ * 7;

        /*
         * If we've tried to handle more than 5 bytes, this encoding doesn't
         * make sense.
         */
        if ($b > 5) {
            return false;
        }

        /*
         * If the top bit was 1, then we still have more bytes to read to
         * represent this number. Otherwise, we are done reading this
         * number.
         */
        if (($c & 0x80) != 128) {
            break;
        }
    }
    return $a;
}

, , , :

$stream = "\x01"; /* This is pretty obviously 1 */
$stream = "\x81\x80\x80\x00";
    /* This is also 1, can you figure out why? */

$stream = "\xff\x01"; /* You might think it 256, but this is 255 */
$stream = "\x80\x82"; /* This is 256. */
$stream = "\xff\xff\x01"; /* 32767 */
$stream = "\x80\x80\x02"; /* 32768 */

$stream = "\x0c\x00\x48\x65\x6c\x6c\x6f\x2c\x20\x77\x6f\x72\x6c\x64\x21"
    /*
     * A static value 13, a length terminator, and 13 bytes that happen 
     * to represent "Hello, world!".
     * This shows how such an encoding would be used in practice
     */

, , little-endian. ( big-endian), : . , . , , , , .

, bytestream - . bytestream. , bytestream ( ). , PPC ARM-, . , .

. , . . Rob Pike , , - - (, bytestream ).

+6

socket_read ,

$packet_length=strlen($c);

, , int (1), , socket_read. , , .

        $c = socket_read($socket, 1);

        $c = socket_read($socket);
0

$c = socket_read($socket, 1024); //1kb read.
if ($c === "") //from documentation - no data is empty string.
  break;

, ,

$str = '';
while(true) {
        $tmp = socket_read($socket, 1024);
        if ($tmp === '')
            break;
        $str .= $tmp;
    }
    return $str;
} 
0

Source: https://habr.com/ru/post/1568839/


All Articles