Presentamos un nuevo y sencillo tutorial para crear servicios de red en Linux, usando PHP y el daemon xinet.d. Como siempre explicaciones paso a paso y fáciles de seguir.

Autor:

Desarrollador y arquitecto Web con más de 10 años de experiencia, especializado en tecnologías Open Source. Experiencia con desarrollos Web en entornos industriales. Puedes leerle en su blog gonzalo123.wordpress.com y también seguirle en Twitter @gonzalo123.

Introducción

No todo en PHP es Web y HTTP. Podemos usar PHP para muchas otras cosas. Por ejemplo podemos crear de una forma muy sencilla servicios de red. Cuando creamos servicios de red necesitamos obviamente un servidor de red (bien sea TCP o UDP).

Cuando trabajamos con Web y HTTP este servidor suele ser Apache (o similares), pero si queremos crear un servicio específico (no HTTP), además del servicio de red que queramos crear, necesitaríamos crear un servidor.

No todo en PHP es Web y HTTP. Podemos usar PHP para muchas otras cosas. Por ejemplo podemos crear de una forma muy sencilla servicios de red.

Esto lo podemos hacer con C, Java e incluso con PHP, pero cuando trabajamos en entornos Linux existe un daemon que nos permite desplegar servicios de red de una forma muy sencilla, encargándose de la parte del servidor y dejándonos a nosotros la parte del servicio de red. Este daemon es xinetd.

Vamos a ver cómo crear un sencillo servicio de red TCP con xinetd y PHP… ¡Empecemos!

Creando el servicio de red TCP con Xinetd y PHP

El ejemplo que vamos a realizar escuchará del puerto 69321, e inicialmente dirá “Hola” cuando alguien realice una petición TCP a dicho puerto. El script del ejemplo es sumamente complicado:

// /home/gonzalo/tests/test1.php
echo "HELLO\n";

Bien. Ahora lo que queremos es que nuestro servicio de red escuche el puerto tcp 60321. Para esto tenemos que definir en nuestro archivo /etc/services el puerto en cuestión:

// /etc/services
...
myService   60321/tcp # my hello service

Y finalmente creamos la configuración en el daemon xinetd. Para ello creamos el archivo /etc/xinetd.d/myService:

# default: on
# description: my test service

service myService
{
        socket_type = stream
        protocol = tcp
        wait = no
        user = gonzalo
        server = /usr/local/bin/php-cli
        server_args = /home/gonzalo/tests/test1.php
        log_on_success += DURATION
        nice = 10
        disable = no
}

Reiniciamos el daemon para que lea la nueva configuración del servicio que hemos creado:

sudo /etc/init.d/xinetd restart

Y listo. Ya tenemos nuestro servicio de red operativo y funcionando. Para probarlo podemos usar un simple telnet al puerto definido:

telnet localhost 60321
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hola
Connection closed by foreign host.

¿Fácil, no? Sí pero útil, no mucho. Por esto vamos a cambiar un poco es script para que acepte variables de entrada. Esto no es HTTP por lo que no podemos usar las típicas variables $_POST y $_GET.

Lo que tenemos que hacer es leer del stdin. En PHP, al igual que con otros lenguajes, esto es muy sencillo:

$handle = fopen('php://stdin','r');
$input = fgets($handle);
fclose($handle);

echo "Hola {$input}";

Reiniciamos el xinetd y tenemos nuestro servicio listo

telnet localhost 60321
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

Vemos que el telnet se nos quedará a la espera que introduzcamos un texto. Escribimos: “gonzalo” y obtenemos:

gonzalo
Hola gonzalo
Connection closed by foreign host.

Conclusión

Y esto es todo. Con este sencillo script vemos que, si bien PHP es un lenguaje destinado principalmente para el desarrollo Web, podemos usarlo para otras cosas, manteniendo su punto fuerte: la sencillez.

¿Para qué nos puede servir esto? Bueno. Para empezar nos sirve para leer datos de dispositivos de red que tengamos por ahi, como báculas, lectores de tarjetas, sensores… Muchos de estos dispositivos suelen permitirnos en su configuración establecer una IP/puerto a la que van a enviar información en forma de trama TCP.

También podemos usarlo para comunicar procesos de una manera simple, sin necesidad de meternos con servidores XMLRPC/Soap y demás. En fin que es una herramienta más que tenemos a nuestra disposición para afrontar nuestros desarrollos.

¡Nos vemos en el próximo artículo!

¿Necesitas desarrollar un proyecto web o para móviles? ¡Estamos disponibles!

Visitar Cokidoo

Cokidoo, los creadores de Ontuts, desarrollamos proyectos tecnológicos centrados en redes sociales y aplicaciones web, aplicaciones móviles y consultoría web y bases de datos.

Somos jóvenes, inquietos, versátiles, apasionados por la innovación y enfocados en las nuevas tecnologías. Con Ontuts tratamos de compartir nuestro conocimiento adquirido en los distintos proyectos, ayudando a la comunidad y mostrando nuestra capacidad tecnológica.

Si necesitas un presupuesto sin compromiso, estamos disponibles, no dudes en contactar con nosotros.

Comentarios en esta publicación (8 comentarios)

¿Te ha gustado esta publicación? ¡Puedes compartir tu opinión con todos nosotros! Simplemente pincha aquí mismo.

que bien que muestres las caras alternas de PHP, aunque incluso se pueden crear los deamos sin necesidad de xinetd aunque este nos evita tener que implementar la lógica para arrancar y parar el deamon… les dejo un deamon para una cosa bien banal como cambiar el wallpapel de Gnome http://www.devtics.com.mx/wp/index.php/376-cambiar-wallpaper-de-gnome-con-php-cli-automaticamente/

Mi experiencia personal creando daemons con PHP es bastante mala. Se puede, pero desde que descubrí xinet.d, ni me lo planteo. El problema es que como dices te tienes que preocupar de arrancarlos y pararlos. Esto tampoco es mucho misterio. Lo que más quebraderos de cabeza me ha dado es la gestión de errores. Si el script casca y no están bien gestionadas las excepciones el daemon se para. OK gestionamos bien las excepciones para que nunca de un error no controlado. Pues bien no todos los errores en PHP son “cacheables”. El ejemplo que he puesto es muy tonto, pero cuando el script es mas complejo, las probabilidades de que falle son mayores. Sobre todo cuando aceptamos tramas de entrada.

Por esto me encanta xinet.d. Que el se encargue de la parte daemon y PHP del servicio en si. Es muy sencillo de configurar y funciona de cine. La incidencia mas grave que me ha dado es que se me olvide poner que arranque al inicio y me quede sin daemon al reiniciar la máquina.

Hace años usaba python para este tipo de scripts (scripts no web), pero de un tiempo a esta parte estoy usando PHP también aqui y los resultados son muy satisfactorios.

Muy interesante.

Una pregunta así rápida. ¿Podría valer para un juego multijugador online en PHP? Un servidor que controle el juego, y luego los clientes… ¿o sería mejor otra cosa?

Por poder si, pero yo no lo usaría. Yo esas cosas tiraría de servidores dedicados con node.js, tornado o similares, sobre todo si los sockets van a estar mucho tiempo alive. De todas formas no tengo experiencia en el tema.

+1 a lo que dice Gonzalo, node.js es realmente potente para ese tipo de cosas.

Buen artículo, no sabía que era tan fácil crear servicios TCP con Xinetd.

Ya se algo más para cuando toque usarlo.. :)

Adolfo Leon Hernandez Abadia

En el mom,ento tengo una aplicacion con socket y corri perfecto ./sena y captura los datos por el puesto y los inserta a una tabla en una base de datos Mysql, perso cuando activa por xinetd.d no inserta los datos.

Como puedo ejecutar la aplicacion en que esta escrita y compilada con leguaje C

12/2/9@14:38:02: START: mysena pid=5391 from=172.16.47.100
12/2/9@14:38:02: EXIT: mysena status=2 pid=5391 duration=0(sec)

# default: on
# description: my test service

service mysena
{
flags = REUSE
socket_type = stream
protocol = tcp
port = 15559
bind = 172.16.4.214
wait = no
user = root
server = /usr/local/src/socket3/sena
disable = no
instances = 4
nice = 10
only_from = 172.16.47.252/24
}

Adolfo Hernandez

En el servicio description: my test service el php-cli es el ejecutable de php?

server = /usr/local/bin/php-cli