socket_select
(PHP 4 >= 4.1.0, PHP 5, PHP 7)
socket_select — Запускает системный вызов select() для заданных массивов сокетов с указанным тайм-аутом
Описание
&$read
, array &$write
, array &$except
, int $tv_sec
, int $tv_usec
= 0
) : intsocket_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, $e, 0);
?>
Возвращаемые значения
В случае успешного выполнения socket_select() возвращает количество
ресурсов сокета, содержащихся в измененных массивах, которое может быть равно нулю,
если тайм-аут истечет до того, как произойдет что-то интересное. В случае возникновения ошибки возвращается false
.
Код ошибки может быть получен с помощью
socket_last_error().
Замечание:
Обязательно используйте оператор
===
при проверке на ошибку. Поскольку socket_select() может возвращать 0, сравнение с==
будет оцениваться какtrue
:Пример #2 Анализ результата socket_select()
<?php
$e = NULL;
if (false === socket_select($r, $w, $e, 0)) {
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, $except, 0);
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() - Возвращает строку, описывающую ошибку сокета