Php socket

De The Linux Craftsman
Aller à la navigation Aller à la recherche

Introduction

Dans le contexte des logiciels, on peut le traduire par « connecteur réseau » ou « interface de connexion ».

Apparu dans les systèmes UNIX, un socket est un élément logiciel qui est aujourd’hui répandu dans la plupart des systèmes d’exploitation. Il s’agit d’une interface logicielle avec les services du système d’exploitation, grâce à laquelle un développeur exploitera facilement et de manière uniforme les services d’un protocole réseau.

[...]

Il s’agit d’un modèle permettant la communication inter processus (IPC - Inter Process Communication) afin de permettre à divers processus de communiquer aussi bien sur une même machine qu’à travers un réseau TCP/IP.

[...]

On distingue ainsi deux modes de communication :

  • Le mode connecté [...] utilisant le protocole TCP. [...]
  • Le mode non connecté [...] utilisant le protocole UDP.

[...]

Les sockets se situent entre la couche transport et les couches applicatives du modèle OSI (protocoles UDP ou TCP utilisant IP / ARP).

Wikipedia

Mise en œuvre

Les socket vont nous permettre de faire communiquer deux processus entre eux grâce à un protocole, généralement un processus appelé serveur et l'autre processus appelé client. C'est pourquoi on parle souvent de protocole client / serveur.

Les fonctions

Tout est détaillé sur le site php.net mais il est important de s'attarder sur certaines fonctions très utiles.

Établissement d'une connexion

Pour créer une socket, il y a deux façons, soit on utilise :

La première méthode va permettre de choisir l'adresse sur laquelle on va placer la socket en écoute ainsi que le type de socket. La deuxième méthode permet uniquement de créer des socket AF_INET (IPv4) de type SOCK_STREAM (TCP).

Si l'objectif est de créer un démon qui écoute sur toutes les interfaces en TCP, la deuxième méthode est plus appropriée.
Au contraire, si l'objectif est de faire de l'IPC, une socket UDP ou même brute (OSI 3), il vaut mieux opter pour la première méthode.

Voici un exemple de socket TCP avec la première méthode.
Ce socket écoute sur le port 1234 de l'interface 127.0.0.1 en TCP :

Voici un exemple de socket TCP avec la deuxième méthode.
Ce socket écoute sur le port 1234 de toutes les interfaces en TCP :

<?php
$socket = socket_create(AF_UNIX, SOCK_STREAM, SOL_TCP);
socket_bind($socket, "127.0.0.1", 1234);
socket_listen($socket);
while($c = socket_accept($socket)) {
	/* Traiter la requête entrante */
}
socket_close($socket);
?>
<?php
$socket = socket_create_listen(0);
while($c = socket_accept($socket)) {
	/* Traiter la requête entrante */
}
socket_close($socket);
?>

Que se passe t-il si le port est déjà utilisé, si les droits ne permettent pas de binder la socket, si le type de socket demandée n'existe pas ? Un erreur survient et regardons maintenant comment l'attraper !

Gestion des erreurs

Pour attraper les erreurs, il faut tester le retour des fonctions énoncées précédemment. Si celui-ci est à FALSE une erreur est survenue et on peut récupérer son code et même une explication textuelle.

Voici un exemple de socket TCP avec la première méthode.

Voici un exemple de socket TCP avec la deuxième méthode.

<?php
if (($socket = socket_create ( AF_UNIX, SOCK_STREAM, SOL_TCP )) == FALSE) {
	echo "socket_create_listen() a échoué : " . socket_strerror ( socket_last_error () ) . "\n";
	exit ( 1 );
}
if(socket_bind ( $socket, "127.0.0.1", 1234 )==FALSE){
	echo "socket_bind() a échoué : " . socket_strerror ( socket_last_error () ) . "\n";
	exit ( 1 );
}
if(socket_listen ( $socket )==FALSE){
	echo "socket_listen() a échoué : " . socket_strerror ( socket_last_error () ) . "\n";
	exit ( 1 );
}
while ( $c = socket_accept ( $socket ) ) {
	/* Traiter la requête entrante */
}
socket_close ( $socket );
?>
<?php
if (($socket = socket_create_listen ( 0 )) == FALSE) {
	echo "socket_create_listen() a échoué : " . socket_strerror ( socket_last_error () ) . "\n";
	exit ( 1 );
}
while ( $c = socket_accept ( $socket ) ) {
	/* Traiter la requête entrante */
}
socket_close ( $socket );
?>

Traitement des connexions entrantes

Traitement multi-client

Modification des options de sockets