Как использовать функцию PHP Pack для упаковки целого числа в байтовый массив? - PullRequest
1 голос
/ 13 июля 2011

Следующий код C # используется в службе, которую я унаследовал, для преобразования небольшого целого числа в 3 байта, чтобы его можно было отправлять через сокет.

int i = 12345;
byte[] data = new byte[] { (byte)i, (byte)(i >> 8), (byte)(i >> 16)};
var result = data[0] + (data[1] << 8) + (data[2] << 16);

Используя PHP, я открываю сокет для сервиса. Протокол связи написан на уровне байтов, поэтому мне нужно отправлять байты через сокет PHP.

Я определил, что для этого мне нужно использовать функцию упаковки.

    <?php
    $binarydata = pack("CCCC", 0xFF, 0x00, 0x00, 0x00);
socket_write($sk, $binarydata, $binarydataLen);
    ?>

Первый байт сообщает серверу, что хочет сделать клиент, и в этом случае следующие 3 байта должны представлять целое число, соответствующее формулам, показанным в реализации c # выше.

Проблема, которая у меня возникла, не имеет значения, что я пытаюсь, я не могу создать 3-байтовый массив из целого числа, соответствующего реализации c #.

Я бы действительно оценил и проголосовал бы за любого, кто может помочь мне решить эту проблему, для опытного разработчика PHP, я думаю, они могли бы знать правильный синтаксис для использования.

Спасибо. Christian

Редактировать: Вот прототип

//The Client
error_reporting(E_ALL);

$address = "127.0.0.1";
$port = <removed>;

/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
} else {
    echo "socket successfully created.\n";
}

echo "Attempting to connect to '$address' on port '$port'...";
$result = socket_connect($socket, $address, $port);
if ($result === false) {
    echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
} else {
    echo "successfully connected to $address.\n";
}

    $value = 17;
    $binarydata = pack("c*", 0xFE, $value & 0x000F, ($value>>8) & 0x000F, ($value>>16) & 0x000F);
    socket_write($socket, $binarydata, 4);
    $input = socket_read($socket, 2048);
    echo "Response from server is: $input\n";


    sleep(5);

echo "Closing socket...";
socket_close($socket);

Ожидаемый результат: «FE 11 00 00» (11 означает 17)

К сожалению, он отправляет "FE 01 00 00" согласно журналам: - (

Сервер отвечает в ASCII, поэтому мне просто нужно правильно указать этот номер, так как он будет динамически меняться.

РЕДАКТИРОВАТЬ: СПАСИБО ВСЕМ, ЕГО РАБОТАЕТ! XD

$binarydata = pack("cc*", 0xFE, $value, ($value>>8), ($value>>16));

Ответы [ 2 ]

1 голос
/ 13 июля 2011

формат "nvc *" неверен. Это сгенерирует 6 байтов. Вы должны сделать это:

    $binarydata = pack("c*", $value & 0x000F, ($value>>8) & 0x000F, ($value>>16) & 0x000F);
1 голос
/ 13 июля 2011

Когда вы пишете упаковочные байты, разве не должна использоваться эта функция?

$binarydata = pack("CCCC", 0xFF, 0x00, 0x00, 0x00);
...