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.