jueves, 17 de noviembre de 2011

Script PHP escucha puertos

Este es un script que puede ser de mucha o poca utilidad lo hice por motivos de aprendizaje, dada la poca documentación en español decidí escribir este artículo que tal vez a alguien le sirva, bien este pequeño script escucha lo que llega a un puerto UDP cualquiera.

<?php
set_time_limit(0); //para que no sea interrumpido el script
while(true){ //iniciamos un bucle infinito para que siempre escuche en el puerto
      $sock=socket_create(AF_INET,SOCK_DGRAM,SOL_UDP); //crea el socket
      if($sock===false){ 
            echo 'socket_create Fallo: '.socket_strerror(socket_last_error());
            break;
      }
      if((socket_bind($sock,"127.0.0.1",2222))===false){ //aquí configuramos la IP
// y el puerto de escucha, por ahora está en localhost para las pruebas, puerto 2222
            socket_close($sock);
            echo 'socket_bind Fallo: '.socket_strerror(socket_last_error());
            break;
      }
      socket_recvfrom($sock,$buf,1024,0,$clientIP,$clientPort); //aquí hace la 
//lectura de lo que está llegando al puerto, 1024 es el tamaño en bites a leer
      if($buf===false){ 
          echo 'socket_recvfrom() Fallo: '.socket_strerror(socket_last_error());
      }elseif(strlen($buf) === 0) {
          echo 'socket_read() Cadena vacia: '.socket_strerror(socket_last_error());
      }
      echo "Lectura: $buf"; //aquí muestra en la pagina lo que lee o podemos 
//agregar el código que por ejemplo envié los datos y los almacene a una base 
//de datos o aun archivo

      // Ahora se puede interactuar con el cliente responder 
      /*if(!socket_connect($sock, $clientIP, $clientPort)){
           echo 'socket_create Fallo: '.$clientIP.':'.$clientPort.' : '.socket_strerror
(socket_last_error());
            socket_close($sock);
      }*/

      socket_close($sock);//se cierra el socket de lo contrario no podrán 
//depositarse datos en el puerto
} 
?>

Ya podrán ajustar el código a sus necesidades, básicamente lo que hace es crear un socket en cada ciclo y conectarse al puerto UDP y empezar a leer y luego cierra el socket esto debe ser así si planeamos interactuar con los clientes ya que si no, no permitirá la conexión de más clientes, indicara que está ocupado, al principio podrá parecer que no funciona pero en realidad está en escucha, para ver que realmente está funcionando utilicen algún programa para enviar datos al puerto UDP y si dicho programa tiene una función para enviar periódicamente datos, mejor aun, por ejemplo que tenga un timmer, pueden ajustarlo para que envié un "hola mundo" cada 500 mili segundos y verán que después de un rato el script libera los echos y sigue ejecutándose y periódicamente mostrara en pantalla la información enviada.

Para propósitos de prueba pueden usar el siguiente programa aunque sea un trial tiene un modulo muy útil que es un cliente UDP y tiene la función timmer para enviar información periódicamente.

http://download.cnet.com/Network-Traffic-Generator-and-Monitor/3000-2085_4-10668961.html

Para hacer lo mismo pero en TCP solo hay que cambiar la línea

$sock=socket_create(AF_INET,SOCK_DGRAM,SOL_UDP); por esta otra

$sock=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);


NOTA MUY IMPORTANTE habrá que habilitar el uso de sockets en PHP para que funcione este script, en el directorio de extensiones del interprete PHP se deberá tener la dll o el .so (linux) llamado php_sockets.dll, además en el archivo php.ini habrá que habilitar dicha extensión con: “extension=php_sockets.dll”

Bueno llegados a este punto resulta que nos daremos cuenta que solo ejecutando un navegador es cómo funciona el script y ahora tenemos el siguiente problema como rayos voy a estar ejecutando el script manualmente, bueno si tu hosting esta en linux la solución es muy simple. Pero en la próxima entrada hablare de cómo hacer para que se ejecute automáticamente.

Nota: el script no es lo más óptimo para esta tarea, lo mejor es una aplicación de escritorio que realice dicha tarea, aunque este script puede cumplir con tareas sencillas, ademas si van a usar bases de datos para almacenar la información que llegue, utilicen conexiones persistentes en php.

Saludos.

1 comentario:

  1. Solo se permite un uso de cada dirección de socket (protocolo/dirección de red/puerto)
    tengo este error...

    ResponderEliminar