Чтение постоянного потока UDP в php - PullRequest
1 голос
/ 29 января 2009

как мне читать данные, которые почти постоянно отправляются на мой сервер. протокол удп. если я пытаюсь прочитать в цикле while (1), я ничего не получаю. кажется, что чтение будет эхом только после того, как все чтение закончено. поэтому он ждет, пока цикл не завершит чтение, которого никогда не будет. я хочу, чтобы socket_read эхом сразу же получал данные. Вот код, который не работает. заранее спасибо.

<?php
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($sock, $local, $port) or die('Could not bind to address');

//this is where the reading loop should go.
while(1)
{
    echo socket_read($sock,1024);
}

socket_close($sock);
?>

Ответы [ 4 ]

3 голосов
/ 29 января 2009

Мне нужно было вызвать ob_flush () ;. Никогда даже не слышал об этом раньше. Оказывается, моя проблема не в цикле, а в том, что php, естественно, ждет, пока скрипт не будет выполнен, прежде чем отправлять внутренний буфер в веб-браузер. вызов flush (); сопровождаемый ob_flush (); заставит php немедленно отправлять в браузер буфер, сохраненный в нем. Это необходимо для сценариев, которые не будут останавливаться (бесконечные циклы) и хотят выводить данные в браузер. Иногда flush () не работает, как в этом случае. Надеюсь, это поможет.

3 голосов
/ 29 января 2009

Попробуйте вызвать flush () сразу после этого оператора echo.

2 голосов
/ 29 января 2009

Ручная запись PHP в socket_read () немного расплывчата, когда речь идет о том, сколько (если таковые имеются) внутренних буферов она выполняет. Учитывая, что вы передаете 1024 для длины, это указывает, что он должен возвращаться после получения не более 1024 байтов данных.

Отказ от ответственности: следующее - просто предположение, так как я не знаю внутренней реализации socket_read ().

Если функция socket_read () использует свой параметр длины в качестве подсказки для внутреннего размера буфера, вы можете столкнуться с плохой производительностью с небольшими пакетами UDP. Например, если socket_read () ожидает 1024 байта данных независимо от размера пакетов, если вы постоянно получаете 60-байтовые UDP-пакеты, потребуется некоторое время для заполнения буфера и возврата функции.

(Примечание: после просмотра поля «unread_bytes», упомянутого Тимом, похоже, что PHP сохраняет внутренние буферы, но не упоминает, насколько они велики или малы.)

В этом случае socket_read () будет возвращать большие порции данных после заполнения буферов, чтобы уменьшить потребление ресурсов обработки, но за счет более высокой задержки. Если вам нужны пакеты как можно раньше, возможно, подойдет установка поля меньшей длины. Это заставит socket_read () возвращаться раньше, хотя и за счет более частого выполнения вашего цикла. Также, если вы установите слишком низкую длину, ваш socket_read () может начать возвращать неполные пакеты, поэтому вам придется учитывать это в своем коде. (Если это имеет значение для вашей заявки, конечно.)

2 голосов
/ 29 января 2009

Как-то так может помочь:

do {
    echo socket_read($handle,1024);
    $status = socket_get_status($handle);
} while($status['unread_bytes']);

OR

while ( $buffer = @socket_read($sock,512,PHP_NORMAL_READ) )
    echo $buffer;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...