получение данных по tcp PHP_BINARY_READ

238
29 января 2018, 07:02

Есть тестовый tcp-сервер.

<?php
function read($sock){
    while($buf = socket_read($sock, 1024, PHP_BINARY_READ ))
        if($buf = trim($buf))
            break;
    return $buf;
}
//error_reporting(E_ALL);
/* Позволяет скрипту ожидать соединения бесконечно. */
set_time_limit(0);
/* Включает скрытое очищение вывода так, что мы получаем данные
 * как только они появляются. */
ob_implicit_flush();
$address = '192.168.1.4';
$port = 8899;
$file = 'log.txt';
file_put_contents($file, "");
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
    echo "Не удалось выполнить socket_create(): причина: " . socket_strerror(socket_last_error()) . "\n";
}
if (socket_bind($sock, $address, $port) === false) {
    echo "Не удалось выполнить socket_bind(): причина: " . socket_strerror(socket_last_error($sock)) . "\n";
}
if (socket_listen($sock, 5) === false) {
    echo "Не удалось выполнить socket_listen(): причина: " . socket_strerror(socket_last_error($sock)) . "\n";
}
do {
    if (($msgsock = socket_accept($sock)) === false) {
        echo "Не удалось выполнить socket_accept(): причина: " . socket_strerror(socket_last_error($sock)) . "\n";
        break;
    }
    /* Отправляем инструкции. */
    $msg = "\nWELCOME TO TEST PHP TCP. \n" .
        "FROM DISCONNECT ENTER 'exit'. FROM POWER LOSS 'power'.\n";
    socket_write($msgsock, $msg, strlen($msg));
    do {
        if(false === ($buf = read($msgsock))){
            echo "Не удалось выполнить socket_read(): причина: $buf\n";
            break 2;
        }
/*        if (false === ($buf = socket_read($msgsock, 2024, PHP_BINARY_READ))) {
            echo "Не удалось выполнить socket_read(): причина: $buf\n";
            break 2;
        }*/
        $buf = $buf . "\r\nNEW LINE \r\n" . bin2hex ($buf);
        if (!$buf = trim($buf)) {
            continue;
        }
        if ($buf == 'exit') {
            break;
        }
        if ($buf == 'power') {
            socket_close($msgsock);
            break 2;
        }
        $talkback = "0x02 0x01 0x01";
        // Открываем файл для получения существующего содержимого
        $current = file_get_contents($file);
        // Добавляем новую информацию в файл
        $current .= "$buf\r\n";
        // Пишем содержимое обратно в файл
        file_put_contents($file, $current);
        socket_write($msgsock, $talkback, strlen($talkback));
        echo "$buf\n";
    } while (true);
    socket_close($msgsock);
} while (true);
socket_close($sock);
?>

На него отправляет запросы контроллер USR-R16-T, вот документация. Используем тип PHP_BINARY_READ. Как видно по коду, полученную информацию сохраняю в файл. Причём как в первозданном виде так и пытаюсь сделать bin2hex. Первая команда приходит при подключении контроллера. Остальные при выполнение команды включения всех релюх на нём. Третья - выключения.

  • Z№"йµ
  • NEW LINE
  • 5ab9221be9b5 ЄU „ ‡
  • NEW LINE
  • aa55000300840087
  • ЄU …‰
  • NEW LINE
  • aa55000300850189
  • ЄU „ ‡
  • NEW LINE
  • aa55000300840087

Вопрос, как мне получить данные вида "0x81 0x01 0x00" как сказано в мануале. Либо какие-то приемлемые данные для работы

Answer 1

Немного переписал с комментариями

<?php
function prettyHex($str) {
    $str = trim($str);
    // дробим строку по два символа
    $out = chunk_split(bin2hex($str), 2, ' ');
    // создаем массив из строки
    $out = explode(' ',$out);
    // добавляем к каждому элементу 0x
    foreach($out as $k=>$v) { if (!empty($v)) $out[$k] = '0x'.$out[$k]; }
    // возвращаем схлопнутый в строку массив
    return implode(" ",$out);
}
function read($sock){
    while($buf = socket_read($sock, 1024, PHP_BINARY_READ ))
        if($buf = trim($buf))
            break;
    return $buf;
}
//error_reporting(E_ALL);
/* Позволяет скрипту ожидать соединения бесконечно. */
set_time_limit(0);
/* Включает скрытое очищение вывода так, что мы получаем данные
 * как только они появляются. */
ob_implicit_flush();
$address = '192.168.1.4';
$port = 8899;
$file = 'log.txt';
file_put_contents($file, "");
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
    echo "Не удалось выполнить socket_create(): причина: " . socket_strerror(socket_last_error()) . "\n";
}
if (socket_bind($sock, $address, $port) === false) {
    echo "Не удалось выполнить socket_bind(): причина: " . socket_strerror(socket_last_error($sock)) . "\n";
}
if (socket_listen($sock, 5) === false) {
    echo "Не удалось выполнить socket_listen(): причина: " . socket_strerror(socket_last_error($sock)) . "\n";
}
do {
    if (($msgsock = socket_accept($sock)) === false) {
        echo "Не удалось выполнить socket_accept(): причина: " . socket_strerror(socket_last_error($sock)) . "\n";
        break;
    }
    /* Отправляем инструкции. */
    $msg = "\nWELCOME TO TEST PHP TCP. \n" .
        "FROM DISCONNECT ENTER 'exit'. FROM POWER LOSS 'power'.\n";
    socket_write($msgsock, $msg, strlen($msg));
    do {
        if(false === ($buf = read($msgsock))){
            echo "Не удалось выполнить socket_read(): причина: $buf\n";
            break 2;
        }
        // этот блок с if'ами перенес выше переназначения переменной buf. Иначе они просто не сработают.
        if (!$buf = trim($buf)) { // тут какая-то не интуитивная логика с присвоением внутри проверки.
            continue;
        }
        if ($buf == 'exit') {
            break;
        }
        if ($buf == 'power') {
            socket_close($msgsock);
            break 2;
        }
        // тут заменил на нашу новую функцию.
        $buf = $buf . "\r\nNEW LINE \r\n" . prettyHex($buf) . "\r\n";
        $talkback = "0x02 0x01 0x01";
        // Открываем файл для получения существующего содержимого
        $current = file_get_contents($file);
        // Добавляем новую информацию в файл
        $current .= "$buf\r\n";
        // Пишем содержимое обратно в файл
        file_put_contents($file, $current);
        socket_write($msgsock, $talkback, strlen($talkback));
        echo "$buf\n";
    } while (true);
    socket_close($msgsock);
} while (true);
socket_close($sock);
?>
READ ALSO
Стили для шаблона gantry

Стили для шаблона gantry

Скажите, пожалуйста, где можно поменять стили для шаблона gantryКеш я очистила, в настройке шаблона и настройках сайта(не кешировать файлы)

227
Как правильно составить запрос к Mysql? [дубликат]

Как правильно составить запрос к Mysql? [дубликат]

На данный вопрос уже ответили:

217
Вконтакте чат-бот на php [требует правки]

Вконтакте чат-бот на php [требует правки]

Здравствуйте, хочу написать чат-бота для вк,написал,подключил к хостингу,ссылку подключил к группе,вроде всё должно работать,но не работает(...

272
API VK не подцепляет opengraph

API VK не подцепляет opengraph

Картинка и title не подгружаются с сайтаКак решить проблему?

275