Aktueller Standort: Startseite> Neueste Artikel> Das Aufrufen von Stream_Socket_Shutdown in PHP führt zu einer Unterbrechung der Verbindungsausnahme. Wie vermeiden und reparieren Sie es?

Das Aufrufen von Stream_Socket_Shutdown in PHP führt zu einer Unterbrechung der Verbindungsausnahme. Wie vermeiden und reparieren Sie es?

M66 2025-06-22

In der PHP -Netzwerkprogrammierung wird die Funktion stream_socket_shutdown verwendet, um eine bestimmte Richtung (lesen, schreiben oder beides) einer Socket -Verbindung zu schließen. In der tatsächlichen Verwendung stoßen viele Entwickler jedoch auf Probleme wie abnormale Verbindungsunterbrechungen, Clientfehler und sogar Datenverlust nach dem Aufrufen von Stream_Socket_Shutdown . In diesem Artikel wird der Arbeitsmechanismus von stream_socket_shutdown eingehend analysiert, die Ursachen für Verbindungsausnahmen untersucht und Methoden zur Vermeidung und Reparatur angeben.


1. Grundlegende Verwendung von Stream_Socket_Shutdown

Die Funktionsdefinition von stream_socket_shutdown lautet wie folgt:

 bool stream_socket_shutdown(resource $stream, int $how)
  • $ stream : Eine offene Socket -Stream -Ressource.

  • $ Wie : Schließen Sie die Richtung, nehmen Sie den Wert an:

    • Stream_shut_rd (0) Schließen Sie die Lesrichtung

    • Stream_shut_wr (1) Schließen Sie die Schreibrichtung

    • Stream_Shut_RDWR (2) Deaktivieren und Schreiben von Anweisungen ausschalten und schreiben

Zum Beispiel:

 $socket = stream_socket_client("tcp://m66.net:8080", $errno, $errstr, 30);
if (!$socket) {
    die("Verbindung ist fehlgeschlagen: $errstr ($errno)");
}

// Schließen Sie die Schreibrichtung,Gibt an, dass Daten nicht mehr gesendet werden
stream_socket_shutdown($socket, STREAM_SHUT_WR);

Nach dem Aufrufen von Stream_Socket_Shutdown wird eine bestimmte Richtung der Sockel geschlossen, und der Kernel sendet Flossenpakete an den Peer, was angibt, dass die Verbindung geschlossen ist.


2. Warum verursacht das Aufrufen von Stream_Socket_Shutdown eine Ausnahmeunterbrechung der Verbindung?

Die Root -Ursache der Ausnahme ist, dass der Client oder Server bei Verwendung von Stream_Socket_Shutdown das Shutdown -Signal der Verbindung nicht ordnungsgemäß verarbeitet oder die Schließreihenfolge unangemessen ist. Speziell manifestiert als:

  • Schließen Sie die Schreibrichtung im Voraus , wodurch die Verbindung getrennt wird, wenn der Peer die Daten nicht beendet.

  • Gleichzeitig wird die Les- und Schreibrichtung ausgeschaltet , die Daten werden jedoch nicht gelesen, was zu Datenverlust führt.

  • Nach dem Schließen der Schreibrichtung werden die verbleibenden Daten nicht rechtzeitig gelesen , was zu einer abnormalen Verbindung führt.

  • Das Flossenpaket wird nicht vom Peer verarbeitet, was die Verbindung zu Zeitüberschreitungen und Trennung verursacht .

Diese Probleme sind besonders anfällig für TCP-Long-Verbindung oder Kommunikationsszenarien mit Halbduplex.


3 ..

3.1 Wählen Sie vernünftigerweise die Schließrichtung aus

Wenn Sie nur die Daten senden und nicht vorhaben, sie noch einmal zu schreiben, rufen Sie an:

 stream_socket_shutdown($socket, STREAM_SHUT_WR);

Dies bedeutet, dass die Schreibrichtung geschlossen ist, aber die Leserrichtung bleibt immer noch aufbewahrt und wartet auf die vom Gleichaltrigen gesendeten Daten.

Wenn sowohl der Server als auch der Client zuerst die Schreibrichtung ausschalten müssen, stellen Sie sicher, dass der Peer genügend Zeit hat, um die verbleibenden Daten zu lesen.

3.2 Lesen Sie weiterhin Daten, nachdem Sie die Schreibrichtung geschlossen haben

Nach dem Schließen der Schreibrichtung kann die Verbindung die Daten weiterhin lesen. Der allgemeine Ansatz ist:

 // Schließen Sie die Schreibrichtung
stream_socket_shutdown($socket, STREAM_SHUT_WR);

// Lesen Sie weiterhin Peer -Daten, bisEOF
while (!feof($socket)) {
    $data = fread($socket, 8192);
    if ($data === false) {
        break;
    }
    // Verarbeitungsdaten
}

Stellen Sie sicher, dass keine Legacy -Daten nicht gelesen werden.

3.3 Stellen Sie sicher

  • Schließen Sie zunächst die Schreibrichtung und benachrichtigen Sie die zugesandten Peer -Daten.

  • Lesen Sie die Daten, die der Peer zurückgeben kann.

  • Schließen Sie nach dem Lesen die Lesrichtung oder schließen Sie die gesamte Verbindung.

3.4 Stellen Sie angemessene Zeitüberschreitungs- und Ausnahmeberichte fest

Verwenden Sie Stream_Set_Timeout , um das Lese- und Schreiben von Timeout festzulegen, um das Blockieren von Verknüpfungshängen zu vermeiden.


4. Beispiele für gemeinsame Fixes für Verbindungsausnahmen

Das folgende Beispiel zeigt den richtigen Weg, um eine sichere Verbindung auf den Server zu schreiben:

 $server = stream_socket_server("tcp://0.0.0.0:12345", $errno, $errstr);
if (!$server) {
    die("Den Server kann nicht gestartet werden: $errstr ($errno)");
}

$client = stream_socket_accept($server);
if ($client) {
    // Antwortdaten senden
    fwrite($client, "Hello from server\n");

    // Schließen Sie die Schreibrichtung,Benachrichtigen Sie den Client, dass es keine Daten mehr gibt
    stream_socket_shutdown($client, STREAM_SHUT_WR);

    // Lesen Sie die vom Client gesendeten Daten fort
    while (!feof($client)) {
        $data = fread($client, 8192);
        if ($data === false || $data === "") {
            break;
        }
        echo "Empfangene Clientdaten: $data\n";
    }

    // Schließen Sie die Verbindung
    fclose($client);
}

fclose($server);

5. Andere Vorsichtsmaßnahmen

  • Vermeiden Sie es, das Lesen und schreiben Sie gleichzeitig Anweisungen aus, es sei denn, es ist sicher, dass die Kommunikation nicht mehr durchgeführt wird.

  • Vermeiden Sie für lange Verbindungen häufige Aufrufe bei Stream_Socket_Shutdown und verwenden Sie Herzschlagpakete und Timeout -Erkennung vernünftigerweise.

  • Stellen Sie sicher, dass das Protokolldesign des Clients und des Servers klar über das Timing und die Reihenfolge der Verbindungsschließung ist.

  • Verwenden Sie Stream_Set_Blocking und Stream_Set_Timeout, um das Blockieren zu verhindern.


Zusammenfassen

stream_socket_shutdown ist ein wichtiges Werkzeug zum Schließen von Socket -Verbindungen, aber unangemessene Verwendung kann leicht zu abnormalen Verbindungsunterbrechungen führen. Das Verständnis der Semantik der Schließung, der vernünftigen Auswahl der Schlussrichtung und der Sicherstellung der Les- und Schreibreihenfolge der Daten nach dem Schließen ist der Schlüssel zur Vermeidung und Behebung von Problemen. Durch die Kombination der korrekten Zeitüberschreitungseinstellungen und Ausnahmebehandlung können PHP -Netzwerkprogramme stabiler und zuverlässiger werden.