(PHP 4 >= 4.1.0, PHP 5, PHP 7)
socket_select — Ejecuta la llamada a select() del sistema sobre las matrices de sockets dadas con un tiempo límite especificado
&$read
, array &$write
, array &$except
, int $tv_sec
[, int $tv_usec
= 0
] ) : intsocket_select() acepta matrices de sockets y las espera para cambiar el estado. Aquellas que vienen con un fondo de sockets BSD reconocerán que aquellas matrices de recursos socket son de hecho los también llamados conjuntos descriptores de archivos. Se observan tres matrices de recursos socket independientes.
read
Los sockets listados en la matriz read
serán
observados para ver si los caracteres están disponibles para lectura (más
precisamente, para ver si una lectura no bloqueará - en particular, un recurso
socket también está listo al final del archivo, en cuyo caso un
socket_read() devolverá una cadena de longitud cero).
write
Los sockets listados en la matriz write
serán
observados para ver si una escritura no bloqueará.
except
Los sockets listados en la matriz except
serán
observados para excepciones.
tv_sec
tv_sec
y tv_usec
forman juntos el parámetros timeout.
timeout es un límite superior de la cantidad de tiempo
trancurrido antes de que socket_select() devuelva.
tv_sec
puede ser cero, causando que
socket_select() devuelva inmediatamente. Esto es útil
para consultas constantes (polling). Si tv_sec
es NULL
(sin tiempo
línmite), socket_select() puede bloquear indefinidamente.
tv_usec
Al salir, las matrices son modificadas para indicar que recurso socket realmente cambió el estado.
No es necesario pasar cada matriz a
socket_select(). En su lugar, se puede omitir y
usar una matriz vacía o NULL
. No olvide también que esas matrices son
pasadas por referencia y serán modificadas después de
que socket_select() devuelva.
Nota:
A causa de una limitación en el Motor Zend actual no es posible pasar una constante como
NULL
directamente como un parámetro a una función que espera que este parámetro sea pasado por referencia. En su lugar use una variable temporal o una expresión que su miembro más a la izquierda sea una variable temporal:Ejemplo #1 Usar
NULL
con socket_select()<?php
$e = NULL;
socket_select($r, $w, $e, 0);
?>
En caso de éxtio, socket_select() devuelve el número de
recursos socket contenidos en las matrices modificadas, lo que puede ser cero si
el tiempo límite expira antes de que ocurra algo interesante. En caso de error se
devuelve FALSE
. El código de error se puede recuperar con
socket_last_error().
Nota:
Asegúrese de usar el operador === cuando verifique un error. Ya que socket_select() puede devolver 0 la comparación con == será evaluada a
TRUE
:Ejemplo #2 Comprender el resultado de socket_select()
<?php
$e = NULL;
if (false === socket_select($r, $w, $e, 0)) {
echo "falló socket_select(), razón: " .
socket_strerror(socket_last_error()) . "\n";
}
?>
Ejemplo #3 Un ejemplo de socket_select()
<?php
/* Preparar la matriz de lectura */
$read = array($socket1, $socket2);
$write = NULL;
$except = NULL;
$núm_sockets_cambiados = socket_select($read, $write, $except, 0);
if ($núm_sockets_cambiados === false) {
/* Manejo de errores */
} else if ($núm_sockets_cambiados > 0) {
/* Ocurrió algo interesante en al menos uno de los sockets */
}
?>
Nota:
Tenga en cuenta que algunas implementaciones de sockets necesitan ser tratadas con mucho cuidado. Unas cuantas reglas básicas:
- Debería siempre intentar usar socket_select() sin tiempo límite. Su programa no debería de hacer nada si no hay información disponible. El código que depende de tiempos límite normalmente no es portable y es difícil de depurar.
- No se deben añadir recursos socket a ningún conjunto si no se pretende verificar su resultado después de la llamada a socket_select(), y responder apropiadamente. Después de que socket_select() devuelva, todos los recursos socket en todas las matrices deben ser verificados. Cualquier recurso socket que esté disponible para escritura debe ser escrito, y cualquier recurso socket disponible para lectura debe ser leído.
- Si lee/escribe en un socket devuelto en las matrices, tenga en cuenta que no necesariamente leerán/escribirán la cantidad de información que solicitó. Esté preparado para que incluso sea capaz de leer/escrir sólo un único byte.
- En la mayoría de las implementaciones de sockets es común que la única expcepción capturada con la matriz
except
sea información fuera de banda recibida en un socket.