Auteur : Armel Fauveau
Adresse d'origine : http://www.phpbuilder.net/columns/armel20010427.php3
Traducteur : Xu [email protected]
Http://www.phpobject.net/blog/
PHP peut ouvrir les sockets de serveurs distants ou locaux ! Voici un exemple simple utilisant des sockets : connectez-vous à un serveur de news Usenet, communiquez avec le serveur et téléchargez quelques articles d'un groupe de news précis.
Ouvrir Socket en utilisant PHP
Utilisez fsockopen() pour ouvrir un Socket. Cette fonction existe en PHP3 et PHP4. Le prototype de la fonction est le suivant :
<?php
intfsockopen
(chaîne nom d'hôte,
port int[,
numéro d'erreur int[,
chaîne errstr[,
double délai d'attente]]])
?>
Pour les hôtes réseau, il établira une connexion TCP Socket avec le port du nom d'hôte. Le nom d'hôte peut être un nom de domaine ou une adresse IP. Pour les connexions UDP, vous devez spécifier le protocole : udp://hostname. Pour les hôtes Unix, le nom d'hôte sera utilisé dans le chemin d'accès au socket et le port doit être défini sur 0 dans cet exemple. Le délai d'expiration facultatif peut être utilisé pour définir le nombre de secondes d'expiration de la connexion.
Plus d'informations sur fsockopen() peuvent être trouvées sur http://www.php.net/manual/function.fsockopen.php
Protocole de transfert de nouvelles sur le réseau (NNTP)
L'accès à un serveur de news Usenet nécessite l'utilisation d'un protocole spécial appelé NNTP, la norme Network News Transfer Protocol. Les détails de ce protocole se trouvent dans la RFC977, que vous pouvez consulter sur http://www.w3.org/Protocols/rfc977/rfc977.html . Ce document décrit en détail comment utiliser différentes commandes pour se connecter et parler à un serveur NNTP.
Serveur de connexion La connexion à un serveur NNTP nécessite de connaître le nom d'hôte (ou l'adresse IP) du serveur et le port sur lequel il écoutera. Il est également recommandé d'ajouter un délai d'attente afin que le programme ne se « fige » pas en cas d'échec de la connexion.
<?php
$cfgServer="votre.news.host";
$cfgPort =119 ;
$cfgTimeOut =10 ;
// ouvre une socket
si(!$cfgTimeOut)
// sans délai d'attente
$usenet_handle=fsockopen($cfgServer,$cfgPort);
autre
// avec délai d'attente
$usenet_handle=fsockopen($cfgServer,$cfgPort, &$errno, &$errstr,$cfgTimeOut);
si(!$usenet_handle) {
echo "Échec de la connexionn" ;
sortie();
}
autre {
echo"Connectén";
$tmp=fgets($usenet_handle,1024);
}
?>
Interagir avec le serveur Nous sommes maintenant connectés au serveur et pouvons interagir avec le serveur via la connexion socket précédemment ouverte. Disons au serveur "Nous voulons obtenir les 10 derniers articles d'un certain groupe de discussion". La RFC977 définit la commande permettant de sélectionner le bon regroupement d'actualités, comme suit :
GROUPggg
Le paramètre requis ggg est le nom du groupe de discussion que vous souhaitez sélectionner, tel que net.news. En utilisant la commande list, vous pouvez obtenir une liste d'actualités valide. Une réponse de sélection réussie renverra les numéros d'actualités du premier et des deux derniers articles d'actualité du groupe ainsi qu'une estimation des numéros d'actualités archivés.
Par exemple
chrome :~$ telnetmy.news.host 119
J'essaie aa.bb.cc.dd...
Connecté à my.news.host.
Le caractère d'échappement est '^]'.
200 my.news.hostInterNetNews Serveur NNRP INN 2.2.2 13 décembre 1999 prêt (publication ok).
GROUPE alt.test
211 232 222996 223235alt.test
quitter
205.
Après avoir reçu la commande "GROUP alt.test", le serveur de news a renvoyé "211232 222996 223235 alt.test". 211 est le code d'identification RFC (une explication simple indiquant que la commande a été exécutée avec succès - consultez RFC pour des informations plus détaillées. Les informations renvoyées indiquent qu'il existe 232 articles, parmi lesquels le numéro d'index de l'actualité la plus ancienne est 222996, et le code d'identification RFC. dernier Le numéro d'index des actualités est 223235. Faisons maintenant le calcul : 222996+232 n'est pas égal à 232235. L'article manquant a été soit supprimé du serveur, soit annulé par son auteur (oui, c'est possible et facile à faire), soit supprimé.
Par précaution, le serveur peut demander une authentification avant de sélectionner un groupe de discussion, selon que le serveur est public ou privé. En général, tout le monde est autorisé à obtenir des informations, mais la publication d'informations nécessite une certification.
<?php
//$cfgUtilisateur = "xxxxxx";
//$cfgPasswd = "aaaaaa";
$cfgNewsGroup="alt.php";
// identification requise sur serveur privé
si($cfgUtilisateur) {
fputs($usenet_handle,"AUTHINFO USER".$cfgUser."n");
$tmp=fgets($usenet_handle,1024);
fputs($usenet_handle,"AUTHINFOPASS".$cfgPasswd."n");
$tmp=fgets($usenet_handle,1024);
// vérifie l'erreur
si($tmp!="281Okrn") {
echo "502Erreur d'authentificationn" ;
sortie();
}
}
// sélectionne le groupe de discussion
fputs($usenet_handle,"GROUP ".$cfgNewsGroup."n");
$tmp=fgets($usenet_handle,1024);
if($tmp=="480 Authentification requise pour la commandern") {
echo "$tmpn" ;
sortie();
}
$info=split(" ",$tmp);
$premier=$info[2];
$last=$info[3];
print"Premier : $firstn";
print"Dernier : $derniern";
?>
Obtenir des articles Maintenant que nous avons le numéro d'index A du dernier article, nous pouvons facilement obtenir les dix derniers articles. La RFC977 indique que la commande ARTICLE peut être utilisée avec le numéro d'index de l'article ou l'ID du message. Par souci de prudence, ici, le numéro d'index de l'article et l'ID du message sont différents. Étant donné que chaque serveur de nouvelles a des définitions différentes, le numéro d'index du même article sur différents serveurs de nouvelles sera différent, mais l'ID du message doit l'être. unique. (Inclus dans l’en-tête de l’article)
<?php
$cfgLimite =10 ;
// télécharger les derniers articles
$boucle=$last-$cfgLimit;
while ($boucle<=$dernier) {
set_time_limit(0);
fputs($usenet_handle,"ARTICLE$bouclen");
$article="";
$tmp=fgets($usenet_handle,4096);
si(substr($tmp,0,3) !="220") {
echo"+----------------------+n";
echo"Erreur sur l'article $bouclen";
echo"+----------------------+n";
}
autre {
while($tmp!=".rn") {
$tmp=fgets($usenet_handle,4096);
$article=$article.$tmp;
}
echo"+----------------------+n";
echo"Article$bouclen";
echo"+----------------------+n";
echo"$articlen";
}
$boucle++;
}
?>
Nous ne recevons que les dix dernières nouvelles de ce groupe sur ce serveur. Vous pouvez également utiliser la commande HEAD pour obtenir les informations d'en-tête de l'article, ou la commande BODY pour obtenir le corps de l'actualité.
Fermez la connexion et utilisez la fonction fclose() pour terminer la session avec le serveur NNTP. Bien entendu, vous pouvez créer un nouveau fichier, comme suit :
<?php
// ferme la connexion
fclose($usenet_handle);
?>
Pour plus d'informations sur fclose(), veuillez consulter : http://www.php.net/manual/function.fclose.php
Conclusion Dans cet article, nous avons montré comment ouvrir, utiliser et fermer une connexion socket dans certaines circonstances : se connecter à un serveur NNTP et récupérer certains articles du groupe de discussion. Publier un article sur un serveur NNTP à l'aide de la commande POST n'est pas beaucoup plus compliqué.
L'étape suivante consiste donc à écrire un client de nouvelles (et à supprimer Netscape) qui peut facilement enregistrer des articles et les indexer à l'aide d'un moteur de recherche (tel que htgid, http://www.htdig.org/), et il doit y avoir une application WEB qui permet d'effectuer des recherches par mots clés dans les groupes de discussion. Voici un exemple, vous pouvez visiter http://www.phpindex.com/ng/ pour le télécharger.