Función PHP getservbyname(): Todo lo que necesitas saber
Como desarrollador PHP, puede que necesites obtener el número de puerto asociado a un nombre de servicio. La función getservbyname() de PHP lo hace.
Los servicios de red se identifican por nombres conocidos como http, ftp o smtp, pero el sistema operativo enruta el tráfico por número de puerto (80, 21, 25, etc.). La función getservbyname() de PHP busca ese número de puerto leyendo la misma base de datos de servicios que usa el resto del sistema. Esta página explica la sintaxis, qué es esa base de datos, los casos de uso más comunes y los problemas a tener en cuenta.
Sintaxis
getservbyname(string $service, string $protocol): int|falseLa función acepta dos parámetros obligatorios:
$service— el nombre del servicio de Internet, por ejemplo"http","ssh"o"smtp".$protocol— el protocolo de transporte, ya sea"tcp"o"udp". A diferencia de lo que sugiere mucha documentación antigua, este argumento no es opcional; debes pasarlo obligatoriamente.
Devuelve el número de puerto como un entero en caso de éxito, o false si no se encuentra el par servicio/protocolo. Dado que false y un puerto válido pueden parecer similares al evaluar su valor de verdad, utiliza siempre el operador estricto === al comprobar un fallo.
De dónde vienen los datos
getservbyname() no se conecta a nada ni hace suposiciones. Lee una tabla de búsqueda local:
- En Linux y macOS es el archivo
/etc/services. - En Windows es
%SystemRoot%\system32\drivers\etc\services.
Si un servicio no está en ese archivo, la búsqueda falla aunque el servicio "obviamente" exista. El resultado depende por tanto de la máquina que ejecuta el script, no es una constante universal.
Un ejemplo básico
La comprobación === false es importante: separa con claridad un fallo real de un resultado legítimo como el puerto 0 (que sería falso con una comparación no estricta ==).
Buscar varios servicios
En la práctica, a menudo se resuelve un lote de nombres a la vez, por ejemplo para generar un informe de firewall o validar una configuración:
<?php
$services = ["http", "https", "ftp", "smtp", "ssh"];
foreach ($services as $name) {
$port = getservbyname($name, "tcp");
echo $port === false
? "{$name}: not found\n"
: "{$name}: {$port}\n";
}
/*
Output:
http: 80
https: 443
ftp: 21
smtp: 25
ssh: 22
*/TCP vs UDP
El mismo nombre de servicio puede resolver en entradas distintas según el protocolo, y algunos servicios solo existen para uno de ellos. Pasa siempre el protocolo que realmente necesitas:
<?php
var_dump(getservbyname("domain", "tcp")); // int(53) — DNS over TCP
var_dump(getservbyname("domain", "udp")); // int(53) — DNS over UDP
var_dump(getservbyname("ntp", "udp")); // int(123)
var_dump(getservbyname("madeup", "tcp")); // bool(false) — unknown service¿Cuándo usarlo?
- Construir clientes de red de forma dinámica. Resuelve un nombre de servicio a un puerto antes de abrir un socket con
fsockopen()opfsockopen(), de modo que tu código lea"smtp"en lugar del número mágico25. - Validar configuraciones. Confirma que un nombre de servicio de un archivo de configuración es conocido por el host antes de usarlo.
- Informes y herramientas. Traduce nombres de servicio legibles por humanos a puertos para logs, paneles de control o reglas de firewall.
Funciones relacionadas
getservbyport()— la operación inversa: dado un número de puerto y protocolo, devuelve el nombre del servicio.getprotobyname()— busca un número de protocolo (p. ej.tcp→6) por su nombre.
Errores comunes
- Ambos argumentos son obligatorios. Omitir
$protocolgenera un error; no existe un valor predeterminado implícito. - Usa solo comparación estricta. Utiliza
=== falsepara detectar fallos y no malinterpretar el puerto0ni casos extremos con cadenas numéricas. - Resultados dependientes del host. La respuesta proviene de la base de datos de servicios local; un nombre desconocido en una máquina puede resolverse en otra.
- Funciona sin conexión. Sin DNS, sin red — es una búsqueda puramente local en una tabla, por lo que es rápida y segura de llamar con frecuencia.
Resumen
getservbyname() mapea un nombre de servicio y un protocolo a un número de puerto usando la base de datos de servicios del sistema operativo, devolviendo un puerto entero o false cuando el par es desconocido. Combínala con getservbyport() para la dirección inversa y con fsockopen() cuando necesites convertir ese puerto en una conexión real.