◆ Bases des sockets
PHP utilise la bibliothèque de sockets de Berkley pour créer ses connexions. Un socket n’est rien de plus qu’une structure de données. Vous utilisez cette structure de données socket pour démarrer une session entre le client et le serveur. Ce serveur est toujours à l'écoute et se prépare à générer une nouvelle session. Lorsqu'un client se connecte au serveur, il ouvre un port sur lequel le serveur écoute une session. A ce moment, le serveur accepte la demande de connexion du client puis effectue un cycle. Le client peut désormais envoyer des informations au serveur, et le serveur peut envoyer des informations au client.
Pour générer un Socket, vous avez besoin de trois variables : un protocole, un type de socket et un type de protocole public. Vous avez le choix entre trois protocoles lors de la génération d'un socket. Continuez à lire ci-dessous pour obtenir le contenu détaillé du protocole.
Définir un type de protocole public est un élément essentiel de la connexion. Dans le tableau ci-dessous, nous examinons les types de protocoles courants.
Tableau 1 : Nom du protocole/Description de la constante
AF_INET Il s'agit du protocole utilisé par la plupart des sockets, utilisant TCP ou UDP pour la transmission, et est utilisé dans les adresses IPv4.
AF_INET6 est similaire à celui ci-dessus, mais est utilisé pour les adresses IPv6.
Protocole local AF_UNIX, utilisé sur les systèmes Unix et Linux. Il est généralement utilisé lorsque le client et le serveur sont sur la même machine. Tableau 2 : Nom du type de socket/description de la constante.
SOCK_STREAM Ce protocole est une connexion séquentielle, fiable et basée sur un flux d'octets intégré aux données. Il s'agit du type de socket le plus couramment utilisé. Ce socket utilise TCP pour la transmission.
SOCK_DGRAM Ce protocole est un appel de transfert sans connexion de longueur fixe. Ce protocole n'est pas fiable et utilise UDP pour ses connexions.
SOCK_SEQPACKET Ce protocole est une connexion fiable à deux lignes qui envoie des paquets de données de longueur fixe pour la transmission. Ce paquet doit être accepté complètement avant de pouvoir être lu.
SOCK_RAW Ce type de socket fournit un accès réseau unique. Ce type de socket utilise le protocole public ICMP. (ping et traceroute utilisent ce protocole)
SOCK_RDM Ce type est rarement utilisé et n'est pas implémenté sur la plupart des systèmes d'exploitation. Il est fourni pour être utilisé par la couche liaison de données et ne garantit pas l'ordre des paquets. Tableau 3 : Nom du protocole public/description de la constante.
Protocole de message de contrôle Internet ICMP, principalement utilisé sur les passerelles et les hôtes pour vérifier les conditions du réseau et signaler les messages d'erreur.
Protocole de datagramme utilisateur UDP, qui est un protocole de transmission sans connexion et peu fiable
Le protocole de contrôle de transmission TCP, qui est le protocole public fiable le plus couramment utilisé, peut garantir que le paquet de données peut atteindre le destinataire si une erreur se produit pendant le processus de transmission, il renverra le paquet d'erreur.
Maintenant que vous connaissez les trois éléments qui génèrent un socket, nous utilisons la fonction socket_create() en PHP pour générer un socket. Cette fonction socket_create() nécessite trois paramètres : un protocole, un type de socket et un protocole public. La fonction socket_create() renvoie un type de ressource contenant le socket si elle s'exécute correctement. En cas d'échec, elle renvoie false.
Ressource socket_create (int protocol, int socketType, int commonProtocol);
Maintenant, vous créez un socket, et alors ? PHP fournit plusieurs fonctions pour manipuler les sockets. Vous pouvez lier un socket à une IP, écouter la communication d'un socket et accepter un socket ; regardons maintenant un exemple pour comprendre comment la fonction génère, accepte et écoute un socket.
<?php
$commonProtocol = getprotobyname("tcp");//Utiliser le nom du protocole public pour obtenir un type de protocole
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);//Générer un socket et renvoyer une instance de la ressource socket
socket_bind($socket, 'localhost', 1337);//Lier le socket à l'ordinateur local
socket_listen($socket);//Écouter toutes les connexions socket entrantes
// Plus de fonctionnalités de socket à venir
?>
L'exemple ci-dessus génère votre propre côté serveur. La première ligne de l'exemple,
$commonProtocol = getprotobyname("tcp");
Utilisez le nom du protocole public pour obtenir un type de protocole. Le protocole public TCP est utilisé ici. Si vous souhaitez utiliser le protocole UDP ou ICMP, vous devez alors modifier les paramètres de la fonction getprotobyname() en "udp" ou "icmp". Une autre alternative consiste à spécifier SOL_TCP ou SOL_UDP dans la fonction socket_create() au lieu d'utiliser la fonction getprotobyname().
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
La deuxième ligne de l'exemple crée un socket et renvoie une instance de la ressource socket. Une fois que vous disposez d’une instance de la ressource socket, vous devez lier le socket à une adresse IP et un port.
socket_bind($socket, 'localhost', 1337);
Ici, vous liez le socket à l'ordinateur local (127.0.0.1) et liez le socket à votre port 1337. Ensuite, vous devez écouter toutes les connexions de socket entrantes.
socket_écouter($socket);
Après la quatrième ligne, vous devez comprendre toutes les fonctions des sockets et leur utilisation.
Tableau 4 : Description du nom de la fonction de la fonction Socket
socket_accept() accepte une connexion Socket
socket_bind() lie le socket à une adresse IP et un port
socket_clear_error() efface l'erreur de socket ou le dernier code d'erreur
socket_close() ferme une ressource socket
socket_connect() démarre une connexion socket
socket_create_listen() ouvre une socket en écoute sur le port spécifié
socket_create_pair() génère une paire de sockets indiscernables dans un tableau
socket_create() génère un socket, ce qui équivaut à générer une structure de données de socket
socket_get_option() Récupère les options de socket
socket_getpeername() Obtient l'adresse IP d'un hôte similaire distant
socket_getsockname() obtient l'adresse IP du socket local
socket_iovec_add() ajoute un nouveau vecteur à un tableau scatter/agrégat
socket_iovec_alloc() Cette fonction crée une structure de données iovec qui peut envoyer, recevoir, lire et écrire
socket_iovec_delete() supprime un iovec alloué
socket_iovec_fetch() renvoie les données de la ressource iovec spécifiée
socket_iovec_free() libère une ressource iovec
socket_iovec_set() définit la nouvelle valeur des données iovec
socket_last_error() récupère le dernier code d'erreur du socket actuel
socket_listen() écoute toutes les connexions du socket spécifié
socket_read() lit les données de la longueur spécifiée
socket_readv() lit les données du tableau scatter/agrégat
socket_recv() termine les données du socket vers le cache
socket_recvfrom() accepte les données du socket spécifié. S'il n'est pas spécifié, il s'agit par défaut du socket actuel.
socket_recvmsg() reçoit des messages d'iovec
socket_select() sélection multiple
socket_send() Cette fonction envoie des données au socket connecté
socket_sendmsg() envoie un message au socket
socket_sendto() envoie un message au socket à l'adresse spécifiée
socket_set_block() définit le socket en mode bloc
socket_set_nonblock() Définit le socket en mode non-blocage
socket_set_option() définit les options de socket
socket_shutdown() Cette fonction vous permet de fermer la lecture, l'écriture ou le socket spécifié
socket_strerror() renvoie l'erreur détaillée avec le numéro d'erreur spécifié
socket_write() écrit des données dans le cache de socket
socket_writev() écrit des données dans des tableaux dispersés/agrégés. Toutes les fonctions ci-dessus sont liées aux sockets en PHP. Pour utiliser ces fonctions, vous devez ouvrir votre socket. Si vous ne l'avez pas ouvert, veuillez modifier votre fichier php.ini et supprimer le. Commentaire suivant avant cette ligne :
extension=php_sockets.dll
Si vous ne parvenez pas à supprimer le commentaire, utilisez le code suivant pour charger la bibliothèque d'extensions :
<?php
if(!extension_loaded('sockets')) {
if(strtoupper(substr(PHP_OS, 3)) == « GAGNER ») {
dl('php_sockets.dll');
}autre{
dl('sockets.so');
}
}
?>
Si vous ne savez pas si votre socket est ouvert, vous pouvez utiliser la fonction phpinfo() pour déterminer si le socket est ouvert. Vous pouvez vérifier si le socket est ouvert en vérifiant les informations phpinfo.
Afficher les informations de phpinfo() sur le socket ◆ Générer un serveur Améliorons maintenant le premier exemple. Vous devez écouter un socket spécifique et gérer les connexions utilisateur.
<?php
$commonProtocol = getprotobyname("tcp");
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);
socket_bind($socket, 'localhost', 1337);
socket_écouter($socket);
// Accepter toutes les connexions entrantes au serveur
$connexion = socket_accept($socket);
si($connexion){
socket_write($connection, "Vous êtes connecté au socket...nr");
}
?>
Vous devez utiliser votre invite de commande pour exécuter cet exemple. La raison en est qu'un serveur sera généré ici, pas une page Web. Si vous essayez d'exécuter ce script à l'aide d'un navigateur Web, il y a de fortes chances qu'il dépasse la limite de 30 secondes. Vous pouvez utiliser le code ci-dessous pour définir une durée d'exécution infinie, mais il est recommandé d'utiliser l'invite de commande pour l'exécuter.
set_time_limit(0);
Testez simplement ce script dans votre invite de commande :
Php.exe exemple01_server.php
Si vous n'avez pas défini le chemin d'accès à l'interpréteur php dans les variables d'environnement de votre système, vous devrez alors spécifier le chemin d'accès à php.exe. Lorsque vous exécutez le serveur, vous pouvez tester le serveur en vous connectant au port 1337 via telnet.
Il y a trois problèmes avec le côté serveur ci-dessus : 1. Il ne peut pas accepter plusieurs connexions. 2. Il n’exécute qu’une seule commande. 3. Vous ne pouvez pas vous connecter à ce serveur via un navigateur Web.
Ce premier problème est plus simple à résoudre, vous pouvez utiliser une application pour vous connecter au serveur à chaque fois. Mais le problème suivant est que vous devez utiliser une page Web pour vous connecter au serveur, ce qui est plus difficile. Vous pouvez demander à votre serveur d'accepter la connexion, d'écrire certaines données sur le client (s'il doit les écrire), de fermer la connexion et d'attendre la prochaine connexion.
Améliorez le code précédent et générez le code suivant pour créer votre nouveau serveur :
<?php
// Configure notre socket
$commonProtocol = getprotobyname("tcp");
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);
socket_bind($socket, 'localhost', 1337); //socket_bind() lie le socket à une adresse IP et un port
socket_écouter($socket);
//Initialiser le tampon
$buffer = "PAS DE DONNÉES" ;
tandis que (vrai) {
// Accepte toutes les connexions arrivant sur cette socket
$connection = socket_accept($socket);//socket_accept() accepte une connexion Socket
printf("Socket connectérn");
// Vérifie s'il y a quelque chose dans le tampon
si($buffer != ""){
printf("Il y a quelque chose dans le tampon...envoi de données...rn");
socket_write($connection, $buffer . "rn"); //socket_write() écrit les données dans le cache du socket
printf("Écrit sur le socketrn");
}autre {
printf("Aucune donnée dans le tamponrn");
}
// Récupère l'entrée
while($data = socket_read($connection, 1024, PHP_NORMAL_READ))//socket_read() lit les données d'une longueur spécifiée
{
$tampon = $données ;
socket_write ($connection, "Informations reçuesrn");
printf("Buffer : " . $buffer . "rn");
}
socket_close($connection); //socket_close() ferme une ressource socket
printf("Fermé le socketrnrn");
}
?>
Que doit faire ce serveur ? Il initialise un socket et ouvre un cache pour envoyer et recevoir des données. Il attend une connexion et une fois la connexion établie, il affiche "Socket connecté" sur l'écran côté serveur. Ce serveur vérifie le tampon et s'il y a des données dans le tampon, il envoie les données à l'ordinateur connecté. Il envoie ensuite un message d'acceptation pour ces données. Une fois qu'il accepte le message, il enregistre le message dans les données, informe l'ordinateur connecté du message et ferme finalement la connexion. Lorsque la connexion est fermée, le serveur commence à traiter la connexion suivante.
◆ Il est facile de générer un client pour gérer le deuxième problème. Vous devez générer une page php, vous connecter à un socket, envoyer des données dans son cache et les traiter. Ensuite, vous avez les données traitées en attente et vous pouvez envoyer vos données au serveur. Sur une autre connexion client, il traitera ces données.
L'exemple suivant illustre l'utilisation de sockets :
<?php
// Crée le socket et se connecte
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$connexion = socket_connect($socket,'localhost', 1337);
while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ)) {
si($buffer == "PAS DE DONNÉES") {
echo("<p>AUCUNE DONNÉE</p>");
casser;
}autre{
// Faire quelque chose avec les données dans le tampon
echo("<p>Données du tampon : " . $buffer . "</p>");
}
}
echo("<p>Écrire sur Socket</p>");
// Écrivez des données de test sur notre socket
if(!socket_write($socket, « CERTAINES DONNÉESrn »)){
echo("<p>Échec de l'écriture</p>");
}
// Lit n'importe quelle réponse du socket
while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ)){
echo("<p>Les données envoyées étaient : CERTAINES DONNÉES<br> La réponse était :" . $buffer . "</p>");
}
echo("<p>Lecture terminée depuis Socket</p>");
?>
Cet exemple de code montre le client se connectant au serveur. Le client lit les données. S'il s'agit de la première connexion à arriver dans ce cycle, le serveur renverra "NO DATA" au client. Si cela se produit, le client est au top de la connexion. Le client envoie ses données au serveur, les données sont envoyées au serveur et le client attend une réponse. Une fois la réponse reçue, il écrit la réponse sur l'écran.