Recherche…


Socket client TCP

Création d'un socket utilisant le protocole TCP (Transmission Control Protocol)

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

Assurez-vous que le socket est créé avec succès. La fonction onSocketFailure provient de l'exemple de manipulation des erreurs de socket dans cette rubrique.

if(!is_resource($socket)) onSocketFailure("Failed to create socket");

Connectez la prise à une adresse spécifiée

La deuxième ligne échoue normalement si la connexion échoue.

socket_connect($socket, "chat.stackoverflow.com", 6667)
        or onSocketFailure("Failed to connect to chat.stackoverflow.com:6667", $socket);

Envoi de données au serveur

La fonction socket_write envoie des octets via une socket. En PHP, un tableau d'octets est représenté par une chaîne, qui est normalement insensible au codage.

socket_write($socket, "NICK Alice\r\nUSER alice 0 * :Alice\r\n");

Recevoir des données du serveur

L'extrait suivant reçoit des données du serveur à l'aide de la fonction socket_read .

Passer PHP_NORMAL_READ comme troisième paramètre lit jusqu'à un octet \r / \n , et cet octet est inclus dans la valeur de retour.

Passer PHP_BINARY_READ , au contraire, lit la quantité de données requise à partir du flux.

Si socket_set_nonblock été appelé auparavant et que PHP_BINARY_READ est utilisé, socket_read renverra false immédiatement. Sinon, la méthode bloque jusqu'à ce que suffisamment de données (pour atteindre la longueur du deuxième paramètre ou pour terminer une ligne) soient reçues ou que le socket soit fermé.

Cet exemple lit les données d'un serveur supposé IRC.

while(true) {
    // read a line from the socket
    $line = socket_read($socket, 1024, PHP_NORMAL_READ);
    if(substr($line, -1) === "\r") {
        // read/skip one byte from the socket
        // we assume that the next byte in the stream must be a \n.
        // this is actually bad in practice; the script is vulnerable to unexpected values
        socket_read($socket, 1, PHP_BINARY_READ);
    }

    $message = parseLine($line);
    if($message->type === "QUIT") break;
}

Fermer la prise

La fermeture du socket libère le socket et ses ressources associées.

socket_close($socket);

Socket serveur TCP

Création de socket

Créez un socket qui utilise le protocole TCP. C'est la même chose que la création d'un socket client.

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

Socket binding

Lier les connexions d'un réseau donné (paramètre 2) pour un port spécifique (paramètre 3) à la prise.

Le deuxième paramètre est généralement "0.0.0.0" , qui accepte la connexion de tous les réseaux. Ça peut aussi

Une cause commune des erreurs de socket_bind est que l'adresse spécifiée est déjà liée à un autre processus . Les autres processus sont généralement supprimés (généralement manuellement pour éviter de tuer accidentellement des processus critiques) afin que les sockets soient libérés.

socket_bind($socket, "0.0.0.0", 6667) or onSocketFailure("Failed to bind to 0.0.0.0:6667");

Mettre une prise à l'écoute

Faites en socket_listen le socket écoute les connexions entrantes en utilisant socket_listen . Le second paramètre est le nombre maximal de connexions permettant la mise en file d'attente avant leur acceptation.

socket_listen($socket, 5);

Connexion de manutention

Un serveur TCP est en réalité un serveur qui gère les connexions enfants. socket_accept crée une nouvelle connexion enfant.

$conn = socket_accept($socket);

Le transfert de données pour une connexion à partir de socket_accept est le même que pour un socket client TCP .

Lorsque cette connexion doit être fermée, appelez socket_close($conn); directement. Cela n'affectera pas le socket du serveur TCP d'origine.

Fermer le serveur

En revanche, socket_close($socket); devrait être appelé lorsque le serveur n'est plus utilisé. Cela libérera également l'adresse TCP, permettant aux autres processus de se lier à l'adresse.

Gestion des erreurs de socket

socket_last_error peut être utilisé pour obtenir l'ID d'erreur de la dernière erreur provenant de l'extension sockets.

socket_strerror peut être utilisé pour convertir l'ID en chaînes lisibles par l'homme.

function onSocketFailure(string $message, $socket = null) {
    if(is_resource($socket)) {
        $message .= ": " . socket_strerror(socket_last_error($socket));
    }
    die($message);
}

Socket serveur UDP

Un serveur UDP (User Datagram Protocol), contrairement à TCP, n'est pas basé sur les flux. Il est basé sur des paquets, c'est-à-dire qu'un client envoie des données dans des unités appelées "paquets" au serveur, et le client identifie les clients par leur adresse. Il n'y a pas de fonction intégrée qui relie les différents paquets envoyés par le même client (contrairement à TCP, où les données du même client sont gérées par une ressource spécifique créée par socket_accept ). On peut penser qu’une nouvelle connexion TCP est acceptée et fermée chaque fois qu’un paquet UDP arrive.

Création d'un socket de serveur UDP

$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

Relier un socket à une adresse

Les paramètres sont les mêmes que pour un serveur TCP.

socket_bind($socket, "0.0.0.0", 9000) or onSocketFailure("Failed to bind to 0.0.0.0:9000", $socket);

Envoi d'un paquet

Cette ligne envoie $data dans un paquet UDP à $address : $port .

socket_sendto($socket, $data, strlen($data), 0, $address, $port);

Recevoir un paquet

L'extrait de code suivant tente de gérer les paquets UDP de manière indexée par le client.

$clients = [];
while (true){
    socket_recvfrom($socket, $buffer, 32768, 0, $ip, $port) === true
            or onSocketFailure("Failed to receive packet", $socket);
    $address = "$ip:$port";
    if (!isset($clients[$address])) $clients[$address] = new Client();
    $clients[$address]->handlePacket($buffer);
}

Fermer le serveur

socket_close peut être utilisé sur la ressource de socket du serveur UDP. Cela libère l'adresse UDP, permettant aux autres processus de se lier à cette adresse.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow