vart001
Administrador
    
Desconectado
Mensajes: 1,553

El Mero, mero!
|
 |
« : 02 de Mayo de 2005, 04:21:51 » |
|
Sockets en PHP Usando sockets en PHP para extraer artÃculos de la Usenet PHP puede abrir sockets en servidores remotos o locales. Aquà encontrareis un ejemplo práctico sobre cómo usar estos sockets: conectaremos a un servidor de News Usenet, nos comunicaremos con él, y bajaremos algunos artÃculos. Cómo abrir un socket en PHP Los sockets se abren con fsockopen(). Esta función está disponible tanto en PHP3 como en PHP4. Usa el siguiente formato:
int fsockopen (string hostname, int port [, int errno [, string errstr [, double timeout
En el caso de un dominio de Internet, abrirá un socket TCP conectándose al hostname en el puerto port. hostname puede ser en este caso o bien un nombre de dominio real o bien una dirección IP. Para conexiones UDP , se necesita indicar explÃcitamente el protocolo: udp://hostname. En sistemas Unix, hostname se usará como ruta del socket y el puerto se pondrá a 0. El timeout opcional se puede emplear para definir un timeout en segundos para la llamada del sistema. Más información sobre fsockopen() en: http://www.php.net/manual/es/function.fsockopen.php
Network News Transfer Protocol Para acceder a un servidor de News Usenet, se requiere usar un protocolo especfico, el NNTP, Network News Transfer Protocol. Este protocolo está muy bien definido en el RFC977 (Request For Comment numero 977), que se encuentra en http://www.w3.org/Protocols/rfc977/rfc977.html Este documento describe con precisión como conectarse y hablar con un servidor NNTP, usando los diferentes comandos disponibles para tal efecto.
¿Cómo conectar? Para conectar con un servidor NNTP necesitamos saber su hostname o dirección IP, y el puerto en el que el servidor está corriendo. Deberiamos incluir el timeout, de forma que una llamada erronea, no nos cuelgue la aplicación.
<?php $cfgServer = "your.news.host"; $cfgPort = 119; $cfgTimeOut = 10; // open a socket if(!$cfgTimeOut) // without timeout $usenet_handle = fsockopen($cfgServer, $cfgPort); else // with timeout $usenet_handle = fsockopen($cfgServer, $cfgPort, &$errno, &$errstr, $cfgTimeOut); if(!$usenet_handle) { echo "Connexion failed "; exit(); } else { echo "Connected "; $tmp = fgets($usenet_handle, 1024); } ?>
Hablando con el Servidor Ya estamos conectados al servidor, y podemos hablar con él a través del socket abierto. Supongamos que queremos bajar 10 artÃculos de algún grupo de noticias (news). RFC977 indica que lo primero que hay que hacer es selecionar el grupo de noticias con el comando GROUP:
GROUP ggg
El parámetro ggg es el nombre del grupo de noticias que seleccionamos (por ejemplo: es.comp.os.lin ux.programacio n). Un listado de los grupos de noticias disponibles, se puede conseguir con el comando LIST. La respuesta del servidor nos indicará el número del primer y último artÃculo del grupo, y una estimación de los artÃculos disponibles. Ejemplo:
chrome:~$ telnet my.news.host 119 Trying aa.bb.cc.dd... Connected to my.news.host. Escape character is '^]'. 200 my.news.host InterNetNews NNRP server INN 2.2.2 13-Dec-1999 ready (posting ok). GROUP es.comp.os.lin ux.programacio n 211 232 222996 223235 es.comp.os.lin ux.programacio n quit 205 .
Tras recibir el comando "GROUP es.comp.os.lin ux.programacio n", el servidor de News contesta "211 232 222996 223235 es.comp.os.lin ux.programacio n". 211 es un código definido en el RFC (dice básicamente que el comando se ha ejecutado sin problemas - en el RFC hay más detalles). También ha contestado que hay 232 artÃculos, indexados desde el 222996 hasta el 223235. Estos números se hacen llamar número de artÃculo. Cada artÃculo tiene uno único. Si contamos: 222996 + 232 no da 232235. Los siete que faltan se borrarÃan del servidor de alguna forma. Es posible que se hayan cancelado por el propio autor (sÃ, esto se puede hacer!) o bien se han borrado tras una denuncia de abuso, por ejemplo. Hay que prestar atención al hecho de que el servidor puede requerir autenticación antes de seleccionar el grupo de news, dependiendo de si es público o privado. Incluso puede dejar libre acceso a la lectura de artÃculos, pero necesitar autorización para publicar nuevos artÃculos.
<?php //$cfgUser = "xxxxxx"; //$cfgPasswd = "yyyyyy"; $cfgNewsGroup = "alt.php"; // identification required on private server if($cfgUser) { fputs($usenet_handle, "AUTHINFO USER ".$cfgUser." "); $tmp = fgets($usenet_handle, 1024); fputs($usenet_handle, "AUTHINFO PASS ".$cfgPasswd." "); $tmp = fgets($usenet_handle, 1024); // check error if($tmp != "281 Ok ") { echo "502 Authentication error "; exit(); } } // select newsgroup fputs($usenet_handle, "GROUP ".$cfgNewsGroup." "); $tmp = fgets($usenet_handle, 1024); if($tmp == "480 Authentication required for command ") { echo "$tmp "; exit(); } $info = split(" ", $tmp); $first = $info[2]; $last = $info[3]; print "First : $first "; print "Last : $last "; ?>
Descargando artÃculos Ahora que sabemos cuál es el número del último artÃculo disponible, es fácil bajarse los 10 últimos artÃculos. RFC977 dice que el comando ARTICLE puede ser usado con el número de artÃculo, o bien, con el ID del Mensaje. No es lo mismo una cosa que otra. El primero es un Ãndice que utiliza el servidor de news al que nos conectamos, y el segundo es un Ãndice universal que representa al artÃculo en todos los servidores NNTP. El ID del mensaje es un número que encontramos en la cabecera del mensaje.
<?php $cfgLimit = 10; // upload last articles $boucle=$last-$cfgLimit; while ($boucle <= $last) { set_time_limit(0); fputs($usenet_handle, "ARTICLE $boucle "); $article=""; $tmp = fgets($usenet_handle, 4096); if(substr($tmp,0,3) != "220") { echo "+----------------------+ "; echo "Error on article $boucle "; echo "+----------------------+ "; } else { while($tmp!=". ") { $tmp = fgets($usenet_handle, 4096); $article = $article.$tmp; } echo "+----------------------+ "; echo "Article $boucle "; echo "+----------------------+ "; echo "$article "; } $boucle++; } ?>
AsÃ, habremos bajado los 10 últimos artÃculos de este grupo de noticias en este servidor. Es posible descargar sólo la cabecera de los artÃculos, usando el comando HEAD, o sólo el contenido, usando el comando BODY. Cerrando la Conexión Para finalizar la sesión con el servidor NNTP, simplemente cerramos el socket usando fclose(), igual que si cerraramos un fichero.
<?php // close connexion fclose($usenet_handle); ?>
Más información sobre fclose() en: http://www.php.net/manual/function.fclose.php
Conclusión Hemos aprendido cómo abrir, usar y cerrar un socket en PHP, en un ejemplo práctico: conectándonos a un servidor NNTP y extrayendo algunos artÃculos de un grupo de noticias. Publicar artÃculos usando el comando POST no es mucho más difÃcil. El siguiente paso, serÃa desarrollar una aplicación cliente de News mediante PHP, para librarnos del Outlook. No serÃa tampoco muy difÃcil almacenar los artÃculos, indexarlos con un buscador, como por ejemplo ht://dig (http://www.htdig.org/) y asÃ, obtener una aplicación web para buscar por palabras en los grupos de noticias. Encontramos un ejemplo de una aplicación asà en http://www.phpindex.com/ng/
ArtÃculo original de Armel Fauveau Traducción al Castellano por BankHacker
|