Función PHP socket_get_status(): Todo lo que necesitas saber
Aprende a usar socket_get_status() en PHP para verificar el estado de un stream: timeouts, conexiones cerradas y bytes en buffer.
Cuando lees o escribes en una conexión de red en PHP, a menudo necesitas saber si la conexión sigue activa, si una lectura superó el tiempo de espera o cuántos bytes están esperando en el buffer. La función socket_get_status() responde exactamente estas preguntas: devuelve una instantánea del estado actual de un stream.
Este capítulo explica qué devuelve socket_get_status(), cuándo importa cada campo y cómo usarlo de forma segura con timeouts y streams no bloqueantes.
¿Qué es la función socket_get_status()?
socket_get_status() recupera el estado actual de un recurso stream como un array asociativo. En realidad es un alias de stream_get_meta_data(), por lo que ambas devuelven los mismos datos — socket_get_status() es simplemente el nombre histórico conservado para el código de red.
A pesar del nombre, la función está diseñada para recursos stream — del tipo que devuelven fsockopen(), pfsockopen() o stream_socket_client() — y no para los recursos socket de bajo nivel creados por socket_create(). Pasar el tipo de recurso incorrecto puede generar advertencias de obsolescencia en PHP 8+ y no te dará los datos que esperas.
Cómo usar la función socket_get_status()
Usar la función socket_get_status() es sencillo. Aquí está la sintaxis de la función:
La sintaxis PHP de la función socket_get_status()
socket_get_status(resource $stream): arrayLa función recibe un parámetro:
$stream: El recurso stream cuyo estado deseas recuperar.
Devuelve un array asociativo. Las claves más útiles son:
| Clave | Tipo | Significado |
|---|---|---|
timed_out | bool | true si la última lectura/escritura superó el timeout del stream. |
blocked | bool | true si el stream está en modo bloqueante. |
eof | bool | true si se ha alcanzado el final del stream (conexión cerrada). |
unread_bytes | int | Bytes ya leídos en el buffer interno de PHP pero aún no consumidos. |
stream_type | string | El transporte subyacente, p. ej. tcp_socket/ssl. |
wrapper_type | string | El wrapper que gestiona el stream, p. ej. http. |
mode | string | El modo de acceso con el que se abrió el stream, p. ej. r+. |
Verificar si una conexión sigue abierta
Aquí hay un ejemplo mínimo que abre un stream TCP, lee una línea y usa socket_get_status() para determinar si el servidor ha cerrado la conexión:
¿Cómo usar la función socket_get_status()?
<?php
$stream = fsockopen("tcp://www.example.com", 80, $errno, $errstr, 30);
if (!$stream) {
die("Error: $errstr ($errno)");
}
fwrite($stream, "GET / HTTP/1.0\r\nHost: www.example.com\r\n\r\n");
$line = fgets($stream);
$status = socket_get_status($stream);
echo $status["eof"] ? "Connection closed by server\n" : "Connection still open\n";
fclose($stream);
?>Usamos fsockopen() para crear un stream y verificamos que se creó correctamente antes de hacer cualquier otra cosa. Después de enviar una solicitud y leer una línea con fgets(), el campo eof nos indica si el extremo remoto ha terminado. Siempre cierra el stream con fclose() cuando hayas terminado.
Detectar un timeout de lectura
El campo timed_out es lo que hace que socket_get_status() sea genuinamente útil. Cuando estableces un timeout de lectura con stream_set_timeout() (o socket_set_timeout()), una lectura lenta no lanza una excepción — fgets() simplemente devuelve false. Luego llamas a socket_get_status() para averiguar por qué devolvió false:
<?php
$stream = fsockopen("tcp://www.example.com", 80, $errno, $errstr, 30);
if (!$stream) {
die("Error: $errstr ($errno)");
}
// Wait at most 2 seconds for data before giving up.
stream_set_timeout($stream, 2);
$line = fgets($stream); // We never sent a request, so nothing arrives.
$status = socket_get_status($stream);
if ($status["timed_out"]) {
echo "Read timed out\n";
} else {
echo "Got data\n";
}
fclose($stream);
?>Como no se envió ninguna solicitud, el servidor no tiene nada que responder, el timeout de 2 segundos se activa y el script imprime Read timed out. Sin socket_get_status() no podrías distinguir un timeout de un fin de stream genuino — ambos hacen que fgets() devuelva false.
Cuándo usar socket_get_status()
- Después de una lectura fallida. Que
fgets()/fread()devuelvafalsees ambiguo; compruebatimed_outyeofpara saber qué ocurrió. - Antes de reutilizar una conexión. Inspecciona
eofpara confirmar que un socket keep-alive sigue vivo antes de enviar otra solicitud. - Con streams no bloqueantes. Cuando llamas a
stream_set_blocking()para hacer un socket no bloqueante,unread_bytesyblockedte ayudan a razonar sobre los datos en buffer.
Advertencias
- Solo funciona con recursos stream — no con recursos de
socket_create(). Para estos, usasocket_last_error()/socket_get_option()en su lugar. socket_get_status()refleja el estado del buffer y del timeout en el momento en que la llamas; no sondea activamente la red, por lo que uneofdefalseno garantiza que el par siga siendo alcanzable.- Restablece el indicador de timeout realizando otra lectura exitosa — el array se recalcula en cada llamada.
Conclusión
La función socket_get_status() es una forma ligera de inspeccionar el estado de un socket stream en PHP. Su campo más valioso es timed_out, que te permite distinguir un timeout de lectura de una conexión cerrada — algo que el valor de retorno de fgets() por sí solo no puede hacer. Combinado con eof, unread_bytes y los controles de timeout y bloqueo de stream_set_timeout() y stream_set_blocking(), te proporciona la información necesaria para gestionar las conexiones de red de forma fiable.