Autor: Armel Fauveau
Dirección original: http://www.phpbuilder.net/columns/armel20010427.php3
Traductor: Xu [email protected]
Http://www.phpobject.net/blog/
¡PHP puede abrir sockets de servidores locales o remotos! Aquí hay un ejemplo simple usando sockets: conéctese a un servidor de noticias Usenet, comuníquese con el servidor y descargue algunos artículos de un grupo de noticias específico.
Abrir socket usando PHP
Utilice fsockopen() para abrir un Socket. Esta función existe tanto en PHP3 como en PHP4. El prototipo de la función es el siguiente:
<?php
intfsockabierto
(nombre de host de cadena,
puerto int[,
int error[,
cadena errr[,
doble tiempo de espera]]])
?>
Para los hosts de red, establecerá una conexión TCP Socket al puerto del nombre de host. El nombre de host puede ser un nombre de dominio o una dirección IP. Para conexiones UDP, debe especificar el protocolo: udp://hostname. Para hosts Unix, el nombre de host se utilizará en la ruta al socket y el puerto debe establecerse en 0 en este ejemplo. El tiempo de espera opcional se puede utilizar para establecer el número de segundos de tiempo de espera de la conexión.
Puede encontrar más información sobre fsockopen() en http://www.php.net/manual/function.fsockopen.php
Protocolo de transferencia de noticias en red (NNTP)
Acceder a un servidor de noticias de Usenet requiere el uso de un protocolo especial llamado NNTP, el estándar del Protocolo de transferencia de noticias en red. Los detalles de este protocolo se encuentran en RFC977, que puede ver en http://www.w3.org/Protocols/rfc977/rfc977.html . Este documento describe en detalle cómo utilizar diferentes comandos para conectarse y hablar con un servidor NNTP.
Servidor de conexión Para conectarse a un servidor NNTP es necesario conocer el nombre de host del servidor (o dirección IP) y el puerto en el que escuchará. También se recomienda agregar un tiempo de espera para que el programa no se "congela" cuando falla la conexión.
<?php
$cfgServer="tu.host.de.noticias";
$cfgPuerto =119;
$cfgTimeOut =10;
// abrir un socket
si(!$cfgTimeOut)
// sin tiempo de espera
$usenet_handle=fsockopen($cfgServer,$cfgPort);
demás
// con tiempo de espera
$usenet_handle=fsockopen($cfgServer,$cfgPort, &$errno, &$errstr,$cfgTimeOut);
si(!$usenet_handle) {
echo"Conexión fallidan";
salida();
}
demás {
echo"Conectadon";
$tmp=fgets($usenet_handle,1024);
}
?>
Interactuar con el servidor Ahora estamos conectados al servidor y podemos interactuar con el servidor a través de la conexión de socket abierta anteriormente. Digamos al servidor "Queremos obtener los 10 últimos artículos de un determinado grupo de noticias". RFC977 define el comando sobre cómo seleccionar la agrupación de noticias correcta, de la siguiente manera:
GRUPOggg
El parámetro requerido ggg es el nombre del grupo de noticias que desea seleccionar, como net.news. Usando el comando list puede obtener una lista de noticias válida. Una respuesta de selección exitosa devolverá los números de noticias del primero y los dos últimos artículos de noticias del grupo y una estimación de los números de noticias archivadas.
Por ejemplo
cromo:~$ telnetmy.news.host 119
Probando aa.bb.cc.dd...
Conectado amy.news.host.
El carácter de escape es '^]'.
200 my.news.hostInterNetNews Servidor NNRP INN 2.2.2 13-dic-1999 listo (publicación correcta).
GRUPO prueba alternativa
211 232 222996 223235 prueba alternativa
abandonar
205.
Después de recibir el comando "GROUP alt.test", el servidor de noticias devolvió "211232 222996 223235 alt.test". 211 es el código de identificación RFC (una explicación simple de que el comando se ejecutó con éxito; consulte RFC para obtener información más detallada. La información devuelta indica que hay 232 artículos, entre los cuales el número de índice de las noticias más antiguas es 222996). último El número de índice de noticias es 223235. Ahora hagamos los cálculos: 222996+232 no es igual a 232235. El artículo que falta fue eliminado del servidor, cancelado por su autor (sí, es posible y fácil de hacer) o eliminado.
Como precaución, el servidor puede requerir autenticación antes de seleccionar un grupo de noticias, dependiendo de si el servidor es público o privado. Generalmente, cualquiera puede obtener noticias, pero publicarlas requiere una certificación.
<?php
//$cfgUser = "xxxxxx";
//$cfgPasswd = "yyyyyy";
$cfgNewsGroup="alt.php";
// identificación requerida en el servidor privado
si($cfgUser) {
fputs($usenet_handle,"AUTHINFO USUARIO".$cfgUser."n");
$tmp=fgets($usenet_handle,1024);
fputs($usenet_handle,"AUTHINFOPASS".$cfgPasswd."n");
$tmp=fgets($usenet_handle,1024);
// comprobar error
si($tmp!="281Okrn") {
echo "502Error de autenticaciónn";
salida();
}
}
// seleccionar grupo de noticias
fputs($usenet_handle,"GRUPO ".$cfgNewsGroup."n");
$tmp=fgets($usenet_handle,1024);
if($tmp=="Se requiere autenticación 480 para el comandorn") {
eco "$tmpn";
salida();
}
$info=split(" ",$tmp);
$primero=$información[2];
$ultimo=$info[3];
print"Primero: $primeron";
print"Último: $últimon";
?>
Obtenga algunos artículos Ahora que tenemos el número de índice A del artículo más reciente, podemos obtener fácilmente los diez artículos más recientes. RFC977 establece que el comando ARTICLE se puede utilizar con el número de índice del artículo o el ID del mensaje. Por precaución, aquí el número de índice del artículo y el ID del mensaje son diferentes. Debido a que cada servidor de noticias tiene definiciones diferentes, el número de índice del mismo artículo en diferentes servidores de noticias será diferente, pero el ID del mensaje debe serlo. único (Incluido en el encabezado del artículo)
<?php
$cfgLimit=10;
// subir últimos artículos
$boucle=$último-$cfgLimit;
mientras ($boucle<=$último) {
set_time_limit(0);
fputs($usenet_handle,"ARTÍCULO$bouclen");
$artículo="";
$tmp=fgets($usenet_handle,4096);
if(substr($tmp,0,3) !="220") {
eco"+----------------------+n";
echo"Error en el artículo $bouclen";
eco"+----------------------+n";
}
demás {
mientras($tmp!=".rn") {
$tmp=fgets($usenet_handle,4096);
$artículo=$artículo.$tmp;
}
eco"+----------------------+n";
echo"Artículo$bouclen";
eco"+----------------------+n";
echo"$artículon";
}
$boucle++;
}
?>
Sólo recibimos las diez últimas noticias de este grupo en este servidor. También puede utilizar el comando HEAD para obtener la información del encabezado del artículo o el comando BODY para obtener el cuerpo de la noticia.
Cierre la conexión y use la función fclose() para finalizar la sesión con el servidor NNTP. Por supuesto, puede crear un nuevo archivo, de la siguiente manera:
<?php
// cerrar conexión
fclose($usenet_handle);
?>
Para obtener más información sobre fclose(), consulte: http://www.php.net/manual/function.fclose.php
Conclusión En este artículo, solo mostramos cómo abrir, usar y cerrar una conexión de socket bajo ciertas circunstancias: conectarse a un servidor NNTP y recuperar algunos artículos del grupo de noticias. Publicar un artículo en un servidor NNTP utilizando el comando POST no es mucho más complicado.
Entonces, el siguiente paso es escribir un cliente de noticias (y eliminar algo de Netscape) que pueda guardar fácilmente artículos e indexarlos usando algún motor de búsqueda (como htgid, http://www.htdig.org/), y debe haber una aplicación WEB que puede realizar búsquedas de palabras clave en grupos de noticias. Aquí hay un ejemplo, puede visitar http://www.phpindex.com/ng/ para descargarlo.