Position actuelle: Accueil> Derniers articles> L'appel Stream_Socket_Shutdown dans PHP provoque une interruption d'exception de connexion. Comment l'éviter et le réparer?

L'appel Stream_Socket_Shutdown dans PHP provoque une interruption d'exception de connexion. Comment l'éviter et le réparer?

M66 2025-06-22

Dans la programmation du réseau PHP, la fonction Stream_Socket_Shutdown est utilisée pour fermer une certaine direction (lire, écrire ou les deux) d'une connexion à socket. Cependant, dans une utilisation réelle, de nombreux développeurs rencontrent des problèmes tels que l'interruption de connexion anormale, les erreurs du client et même la perte de données après l'appel Stream_Socket_Shutdown . Cet article analysera le mécanisme de travail de Stream_Socket_Shutdown en profondeur, explorera les causes des exceptions de connexion et donnera des méthodes pour éviter et réparer.


1. Utilisation de base de Stream_Socket_Shutdown

La définition de la fonction de Stream_Socket_Shutdown est la suivante:

 bool stream_socket_shutdown(resource $stream, int $how)
  • $ Stream : une ressource de flux de socket ouvert.

  • $ comment : fermez la direction, prenez la valeur:

    • Stream_shut_rd (0) Fermez la direction de lecture

    • Stream_shut_wr (1) Fermez la direction d'écriture

    • Stream_shut_rdwr (2) désactiver les instructions de lecture et d'écriture

Par exemple:

 $socket = stream_socket_client("tcp://m66.net:8080", $errno, $errstr, 30);
if (!$socket) {
    die("Échec de la connexion: $errstr ($errno)");
}

// Fermez la direction d'écriture,Indique que les données ne sont plus envoyées
stream_socket_shutdown($socket, STREAM_SHUT_WR);

Après avoir appelé Stream_Socket_Shutdown , une certaine direction de la prise sera fermée et le noyau enverra des paquets de finition au pair, indiquant que la connexion est fermée.


2. Pourquoi l'appel Stream_Socket_Shutdown provoque-t-il une interruption d'exception à la connexion?

La cause profonde de l'exception est que lors de l'utilisation de Stream_Socket_Shutdown , le client ou le serveur ne gère pas correctement le signal d'arrêt de la connexion, ou l'ordre de clôture est inapproprié. Spécifiquement se manifeste comme:

  • Fermez la direction d'écriture à l'avance , ce qui entraîne la déconnexion de la connexion lorsque le pair ne termine pas la lecture des données.

  • Dans le même temps, la direction de lecture et d'écriture est désactivée , mais les données ne sont pas lues, entraînant une perte de données.

  • Après la fermeture de la direction d'écriture, les données restantes ne sont pas lues dans le temps , ce qui entraîne une connexion anormale.

  • Le paquet de nageoires n'est pas traité par le pair, provoquant la connexion au délai d'attente et à la déconnexion .

Ces problèmes sont particulièrement susceptibles de se produire dans les scénarios de communication à longue connexion TCP ou à demi-duplex.


3. Comment éviter Stream_Socket_Shutdown provoquant des interruptions d'exception?

3.1 Sélectionnez raisonnablement la direction de clôture

Si vous envoyez simplement les données et ne prévoyez pas de les rédiger, appelez:

 stream_socket_shutdown($socket, STREAM_SHUT_WR);

Cela signifie que la direction d'écriture est fermée, mais la direction de lecture est toujours conservée, en attendant les données envoyées par le pair.

Si le serveur et le client doivent d'abord désactiver la direction d'écriture, assurez-vous que le pair a suffisamment de temps pour lire les données restantes.

3.2 Continuer à lire les données après la fermeture de la direction d'écriture

Après la fermeture de la direction d'écriture, la connexion peut toujours lire les données. L'approche générale est:

 // Fermez la direction d'écriture
stream_socket_shutdown($socket, STREAM_SHUT_WR);

// Continuez à lire les données des pairs jusqu'àEOF
while (!feof($socket)) {
    $data = fread($socket, 8192);
    if ($data === false) {
        break;
    }
    // Traitement des données
}

Assurez-vous qu'aucune donnée héritée n'est lue.

3.3 Assurez-vous que l'ordre de clôture de la connexion est correct

  • Tout d'abord, fermez la direction d'écriture et informez les données des pairs à envoyer.

  • Lisez les données que le pair peut retourner.

  • Après avoir lu, fermez la direction de lecture ou fermez toute la connexion.

3.4 Définir un délai d'expiration raisonnable et une capture d'exception

Utilisez Stream_Set_timeout pour définir le délai d'expiration de lecture et d'écriture pour éviter le blocage de la connexion.


4. Exemples de correctifs communs pour les exceptions de connexion

L'exemple suivant démontre la bonne façon d'écrire une connexion sécurisée sur le serveur:

 $server = stream_socket_server("tcp://0.0.0.0:12345", $errno, $errstr);
if (!$server) {
    die("Impossible de démarrer le serveur: $errstr ($errno)");
}

$client = stream_socket_accept($server);
if ($client) {
    // Envoyer des données de réponse
    fwrite($client, "Hello from server\n");

    // Fermez la direction d'écriture,Informer le client qu'il n'y a plus de données
    stream_socket_shutdown($client, STREAM_SHUT_WR);

    // Continuez à lire les données envoyées par le client
    while (!feof($client)) {
        $data = fread($client, 8192);
        if ($data === false || $data === "") {
            break;
        }
        echo "Données du client reçu: $data\n";
    }

    // Fermer la connexion
    fclose($client);
}

fclose($server);

5. Autres précautions

  • Évitez de désactiver la lecture et d'écrire des instructions simultanément à moins qu'il ne soit sûr que la communication ne sera plus effectuée.

  • Pour les longues connexions, évitez les appels fréquents vers Stream_Socket_Shutdown et utilisez raisonnablement les packages de battements de cœur et le délai d'expiration.

  • Assurez-vous que la conception du protocole du client et du serveur est claire sur le calendrier et la clôture de la connexion.

  • Utilisez Stream_Set_Blocking et Stream_Set_timeout pour éviter le blocage.


Résumer

Stream_Socket_Shutdown est un outil important pour clôturer les connexions de socket, mais une utilisation inappropriée peut facilement conduire à des interruptions de connexion anormales. Comprendre la sémantique de sa fermeture, sélectionner raisonnablement la direction de fermeture et garantir l'ordre de lecture et d'écriture des données après la fermeture est la clé pour éviter et résoudre les problèmes. La combinaison des paramètres de délai d'expiration corrects et de la gestion des exceptions peut rendre les programmes de réseau PHP plus stables et fiables.