Aktueller Standort: Startseite> Neueste Artikel> socket_accept () steckt? Detaillierte Erläuterung der Unterschiede zwischen Blockier- und nicht blockierenden Modi

socket_accept () steckt? Detaillierte Erläuterung der Unterschiede zwischen Blockier- und nicht blockierenden Modi

M66 2025-05-20

Bei der Verwendung von PHP für die Netzwerkprogrammierung stoßen viele Entwickler häufig auf ein Problem, wenn Sie Socket_accept () verwenden, um einen TCP -Server zu erstellen: Das Programm steckt fest und kann nicht weiter ausführen. Dieses Phänomen beruht hauptsächlich aus dem unzureichenden Verständnis des "Blockierungsmodus" und "Nicht-Blocking-Modus". In diesem Artikel wird erklärt, warum Socket_accept () "festgefahren" und den Unterschied zwischen Blockierung und Nichtblocking-Modi im Detail erläutern.

1. Was ist Socket_accept () ?

Socket_accept () ist eine Funktion in der PHP -Socket -Erweiterung, die Verbindungsanforderungen von Clients akzeptiert. Nachdem Sie einen Socket mit Socket_Create () erstellt haben und Socket_Bind () und Socket_Listen () verwenden, um das Hören zu beginnen, müssen Sie Socket_accept () verwenden, um die Verbindung zu empfangen:

 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8080);
socket_listen($socket);

while (true) {
    $client = socket_accept($socket);
    // Rechts $client Lesen- und Schreibvorgänge ausführen
}

Im obigen Beispiel wird Socket_accept () weiterhin blockieren, während er auf die Verbindung wartet, bis ein Client eine Verbindung herstellt.

2. Warum "steckt es"?

Das sogenannte "Stuck" ist tatsächlich, dass das Programm auf die Verbindung wartet, aber nicht zurückkehrt. Dies ist kein Fehler, sondern ein normales Verhalten im Blockierungsmodus.

Standardmäßig befindet sich der PHP -Socket im Blockierungsmodus. Das heisst:

  • Wenn kein Client mit dem Server verbunden ist, wartet Socket_accept () .

  • Die CPU führt den nachfolgenden Code erst aus, wenn Socket_accept () das Ergebnis zurückgibt.

Wenn Sie also den Server debuggen oder ausführen, ohne eine Client -Verbindung, wird das Programm immer in der Zeile von Socket_accept () "festgefahren".

Dies ist in Produktionsumgebungen akzeptabel, da der Server nur auf die Verbindung warten muss. In Umgebungen, in denen Debugging oder mehrere Aufgaben behandelt werden müssen, kann dieses Blockierungsverhalten zu einem Problem werden.

3.. Lösungen für den Nicht-Blocking-Modus

Wenn Sie möchten, dass das Programm weiterhin ohne Verbindung ausgeführt wird, z. B. regelmäßige Vorgänge durchzuführen oder andere Ereignisse zu erkennen, müssen Sie den Nicht-Blocking-Modus verwenden.

Setzen Sie den nicht blockierenden Modus:

 socket_set_nonblock($socket);

Zu diesem Zeitpunkt wird Socket_accept () nicht mehr warten, sondern stattdessen:

  • Kehren Sie in die Client -Socket zurück, wenn eine Verbindung besteht.

  • Geben Sie falsch sofort zurück, wenn es keine Verbindung gibt, und setzen Sie den Fehlercode auf Socket_EAGAIN oder SOCKKET_EWOLDBLOCK .

Beispielcode:

 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8080);
socket_listen($socket);
socket_set_nonblock($socket);

while (true) {
    $client = @socket_accept($socket);
    if ($client === false) {
        // Keine Verbindung,Mach weiter andere Dinge
        echo "Warten auf die Verbindung...\n";
        sleep(1);
    } else {
        // Erhielt die Verbindung erfolgreich
        socket_write($client, "Hello from m66.net\n");
        socket_close($client);
    }
}

4. Verwenden Sie Socket_Select () , um die Blockierung anmutiger zu verwalten

Eine weitere übliche Praxis ist die Verwendung von Socket_Select () , um festzustellen, ob es Sockets gelesen und geschrieben werden kann, wodurch Blind Loop -Überprüfung vermieden werden kann:

 $read = [$socket];
$write = $except = null;

if (socket_select($read, $write, $except, 5) > 0) {
    $client = socket_accept($socket);
    // Kundenverbindungen umgehen
}

Diese Methode blockiert nicht auf unbestimmte Zeit, da Sie die Zeitüberschreitungszeit festlegen können. Es ist auch für Szenen geeignet, in denen mehrere Sockets gleichzeitig angehört werden und eine gemeinsame Technik in der Hochleistungsnetzwerkprogrammierung ist.

5. Zusammenfassung

  • Socket_accept () blockiert standardmäßig, und wenn es keine Verbindungsanforderung gibt, wird es warten.

  • Das Blockieren von Verhalten ist kein Fehler, aber es wird dazu führen, dass das Programm "stagnieren", während er auf die Verbindung wartet.

  • Sie können Socket_Set_Nonblock () auf den Nicht-Blocking-Modus einstellen, um die Programmstagnation zu vermeiden.

  • Eine fortgeschrittenere Lösung besteht darin , Socket_Select () zu verwenden, um den Zustand mehrerer Sockets zu verwalten.