socket_select

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

socket_selectЗапускает системный вызов select() для заданных массивов сокетов с указанным тайм-аутом

Описание

socket_select ( array &$read , array &$write , array &$except , int $tv_sec , int $tv_usec = 0 ) : int

socket_select() принимает массивы сокетов и ждет их изменения статуса. Те, кто знаком с сокетами BSD, обнаружат, что массивы с ресурсами сокетов на самом деле являются так называемыми наборами дескрипторов файлов. Наблюдаются три независимых массива ресурсов сокетов.

Список параметров

read

Сокеты, перечисленные в массиве read будут наблюдаться для просмотра, есть ли доступные символы для чтения ( точнее, чтобы видеть, не будет ли чтение блокироваться, в частности, ресурс сокета уже достиг конца файла, и в этом случае socket_read() вернет строку с нулевой длиной).

write

Сокеты, перечисленные в массиве write будут наблюдаться для просмотра, не будет ли запись блокироваться.

except

Сокеты, перечисленные в массиве except будут наблюдаться для исключений.

tv_sec

tv_sec и tv_usec вместе образуют параметр timeout. Параметр timeout - максимальный промежуток времени до возврата socket_select(). tv_sec может быть нулём, заставляя socket_select() к немедленному возврату. Это полезно для опроса. Если tv_sec равен null (нет тайм-аута), socket_select() может блокироваться бесконечно.

tv_usec

Внимание

При завершении массивы изменяются для обозначения, какой ресурс сокета на самом деле изменил статус.

Не требуется передавать каждый массив в socket_select(). Вы можете пропустить его и использовать пустой массив или null вместо этого. Также не забывайте, что эти массивы передаются по ссылке и будут изменены после завершения socket_select().

Замечание:

Из-за ограничения текущего движка Zend невозможно передать модификатор константы, такой как null, непосредственно в качестве параметра в функцию, которая ожидает, что этот параметр будет передан по ссылке. Вместо этого используйте временную переменную или выражение, где левая сторона является временной переменной:

Пример #1 Использование null в socket_select()

<?php
$e 
NULL;
socket_select($r$w$e0);
?>

Возвращаемые значения

В случае успешного выполнения socket_select() возвращает количество ресурсов сокета, содержащихся в измененных массивах, которое может быть равно нулю, если тайм-аут истечет до того, как произойдет что-то интересное. В случае возникновения ошибки возвращается false. Код ошибки может быть получен с помощью socket_last_error().

Замечание:

Обязательно используйте оператор === при проверке на ошибку. Поскольку socket_select() может возвращать 0, сравнение с == будет оцениваться как true:

Пример #2 Анализ результата socket_select()

<?php
$e 
NULL;
if (
false === socket_select($r$w$e0)) {
    echo 
"Неудачный вызов socket_select(), причина: " .
        
socket_strerror(socket_last_error()) . "\n";
}
?>

Примеры

Пример #3 Пример использования socket_select()

<?php
/* Подготовить массив сокетов для чтения */
$read   = array($socket1$socket2);
$write  NULL;
$except NULL;
$num_changed_sockets socket_select($read$write$except0);

if (
$num_changed_sockets === false) {
    
/* Обработка ошибок */
} else if ($num_changed_sockets 0) {
    
/* По крайней мере, в одном из сокетов произошло что-то интересное */
}
?>

Примечания

Замечание:

Имейте в виду, что некоторые реализации сокетов необходимо обрабатывать очень осторожно. Несколько основных правил:

  • Вы всегда должны попытаться использовать socket_select() без тайм-аута. Ваша программа ничего не должна делать, если нет доступных данных. Код, зависящий от тайм-аутов, обычно не очень переносим и труден для отладки.
  • Ресурс сокета не должен добавляться к любому из массивов, если вы не собираетесь проверять результат после вызова socket_select(). После возврата socket_select() все ресурсы сокета во всех массивах должны быть проверены. Любой ресурс сокета, доступный для записи или чтения, должен использоваться для записи или чтения.
  • Если вы читаете или записываете из сокета, возвращаемого в массивах, имейте в виду, что он необязательно сможет прочитать или записать полностью запрашиваемые вами данные. Будьте готовы прочитать или записать только один байт.
  • Обычно для большинства реализаций сокетов единственное исключение, пойманное с помощью массива except - это данные без привязки, полученные в сокете.

Смотрите также

  • socket_read() - Читает строку максимальную длину байт из сокета
  • socket_write() - Запись в сокет
  • socket_last_error() - Возвращает последнюю ошибку на сокете
  • socket_strerror() - Возвращает строку, описывающую ошибку сокета