Php , survolons les sockets
Par Christophe de saint leger le jeudi, février 5 2009, 15:38 - PHP - Lien permanent
Nous allons voir dans cet article , l'utilisation des sockets en php Dans quel but , et bien , par curiosité .. simplement ..
Pré-requis :
il nous faut pour les sockets avoir compilé php avec l'option --enable-sockets ... Voilà , rien de plus ..
Que faire ?
Nous allons une partie serveur qui va écouter sur un port donné , et distribuer les messages aux clients qui se connectent . Le but n'est pas d'avoir un programme fini , mais bien d'avoir une première approche avec les sockets en PHP.
Partie Serveur:
Entamons donc notre script serveur.php
Création d'une socket
Nous allons ici , creer la socket , et mettre le script en écoute de connexion ...
set_time_limit(0);
ob_implicit_flush();
try {
//creation du socket
$Psock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
//en cas d'erreur à la creation de la socket
if ( $Psock === FALSE ){
$msgerror = socket_strerror(socket_last_error());
throw new Exception($msgerror);
}
//nommage de la socket cree
$ret = socket_bind($Psock, '127.0.0.1', 10005);
//en cas d'erreur au nommage de la socket
if ( $ret === FALSE ){
$msgerror = socket_strerror(socket_last_error());
throw new Exception($msgerror);
}
//Attente des connexions entrantes
$ret = socket_listen( $Psock, 0 );
//en cas d'erreur
if ( $ret === FALSE ){
$msgerror = socket_strerror(socket_last_error());
throw new Exception($msgerror);
}
//Acceptation des connexions entrantes
//endormissement si aucune connexion
$Csock = socket_accept($Psock);
//en cas d'erreur
if ( $ret === FALSE ){
$msgerror = socket_strerror(socket_last_error());
throw new Exception($msgerror);
}
//Message lor d'une connexion
echo "<br><b>Réception d'une connexion ! </b><br>";
//Souhaitons la bienvenue au client
$ret = @socket_write($Csock, "Welcome<br>", strlen("Welcome<br>"));
//Fermeture de la connexion cliente
if( is_ressource($Csock) ){
socket_close($Csock);
unset($Csock);
}
//fermeture du serveur
if(is_resource($this->Psock)){
socket_close($this->Psock);
unset($this->Psock);
}
}catch (Exception $e){
print_r( $e->getMessage() );
exit(1);
}
Voilà , pour la partie serveur .. comme vous pouvez le voir , il n'y a rien de vraiment palpitant .. ici , une simple connexion .. et hop , le serveur envoie un message au client , puis il s'arrête aussitôt . Nous aurions trés bien pu mettre une boucle infinie pour accepter autant de connexions que possible , ou un message spécifique stop le serveur . En effet, la fonction socket_accept($Psock); est bloquante , c'est à dire que le script s'arrete à cette ligne tant qu'aucune connexion n'a eu lieu , c'est pourquoi nous avons ajouté en debut de script , la ligne : set_time_limit(0); afin de ne pas être limité dans le temps ... pour la suite des possibilités , je laisse libre votre imagination ..
Partie Client :
Pour la partie client , le tout debut , est le même .. mais moins long tout de même ... regardez client.php
/*
* Création d'une socket Inet
*/
try{
$Psock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
//en cas d'erreur à la creation de la socket
if ( $Psock === FALSE ){
$msgerror = socket_strerror(socket_last_error());
throw new Exception($msgerror);
}
/*
* Connexion au serveur
*/
$ret = socket_connect($Psock,'127.0.0.1',10005);
//en cas d'erreur à la creation de la socket
if ( $Psock === FALSE ){
$msgerror = socket_strerror(socket_last_error());
throw new Exception($msgerror);
}
echo $buf = socket_read($Psock, 2048);
socket_close($Psock);
}catch(Exception $e){
print_r( $e->getMessage() );
exit(1);
}
Et voilà pour la partie cliente , comme pour la partie serveur , nous créons une socket via la fonction socket_create() , ensuite , nous tentons une connexion de l'autre coté du "tube" via socket_connect() , si aucune erreur n'est détecté , nous attendons sagement un message du serveur ... socket_read() est aussi bloquant , tant qu'aucun message (ou une chaîne vide) n'arrive , le script reste endormis à cette ligne , toujours sans consommer de ressources ...
Dés réception de données , notre script va simplement l'afficher à l'écran puis se déconnecter ...
Test sans parti serveur
Pour tester trés rapidement les sockets au niveau client , vous pouvez simplement , changer le numéro de port et l'adresse à laquelle vous vous connectez .. exemple , si vous avez ssh sur votre machine , remplacez 10005 par 22 , vous allez voir un message du style :
SSH-2.0-OpenSSH_4.3p2 Debian-9etch3
Ou sur votre serveur de mail , mettez l'adresse de votre serveur , et le port 25
220 mailhost.creavi.fr ESMTP Postfix (Debian/GNU)
Et voilà pour le survol des sockets , qui peut aboutir à de nombreuses applications intéressantes , rien que pour leurs conception ...
Christophe.

