Aktueller Standort: Startseite> Neueste Artikel> So wechseln Sie den Status des Socket_Set_Blocks im nicht blockierenden Hören vorübergehend

So wechseln Sie den Status des Socket_Set_Blocks im nicht blockierenden Hören vorübergehend

gitbox 2025-05-26

Bei Verwendung von Sockets für die Netzwerkprogrammierung in PHP kann der Nicht-Blocking-Modus die gleichzeitigen Verarbeitungsfunktionen verbessern und ist der Schlüssel zur Implementierung von ereignisgesteuerten oder multiplexierten Servern. Manchmal müssen wir jedoch den Socket vorübergehend auf die Blockierung des Zustands einstellen, um bestimmte "Muss" -Operationen abzuschließen, z. B. das Inszenieren eines großen Datenpakets oder das Warten darauf, dass der Client vollständige Handshake -Daten sendet.

Glücklicherweise bietet PHP zwei Funktionen: Socket_Set_Block () und Socket_Set_Nonblock () , die leicht zwischen Blockier- und Nicht-Blocking-Modi wechseln können.

In diesem Artikel wird ein spezifisches TCP-Server-Beispiel kombiniert, um zu demonstrieren, wie der Socket vorübergehend in einen Blockierstatus im nicht blockierenden Hören umgestellt wird und den nicht blockierenden Status nach Abschluss des Vorgangs wiederherstellt.

Beispielszenario

Wir erstellen einen nicht blockierenden TCP-Server, hören die Client-Verbindung an und nach dem Empfangen der Client-Verbindung wechseln wir die Verbindung vorübergehend in den Blockierungsmodus, lesen ein Datenstück vom Client und wechseln nach Abschluss wieder in den nicht blockierenden Modus.

Hier ist der vollständige Code:

<Code> <? Php

$ host = '0.0.0.0';
$ port = 12345;

// Socket erstellen
$ server = socket_create (af_inet, sock_stream, sol_tcp);
SOCKKET_SET_OPTION ($ Server, Sol_Socket, So_Reuseaddr, 1);

// Binden und Zuhören
socket_bind ($ server, $ host, $ port);
socket_listen ($ server);

// auf nicht blockierende einstellen
socket_set_nonblock ($ server);

echo "Server -Hör auf {$ host}: {$ port} ... \ n";

$ clients = [];

while (wahr) {
// Verbindung akzeptieren (nicht blockierend)
$ client = @socket_accept ($ server);
if ($ client! == false) {
echo "neuer Client Connected. \ n";
// zur Client -Liste hinzufügen
$ clients [] = $ client;

     // Stellen Sie den Client auf nicht blockierende
    socket_set_nonblock($client);
}

foreach ($clients as $index => $sock) {
    $buffer = '';

    // Vorübergehend auf Block gesetzt, um die vollständige Lektüre zu gewährleisten(Lesen Sie beispielsweise eine feste Länge oder bis eine Flagge)
    socket_set_block($sock);

    $bytes = @socket_recv($sock, $buffer, 1024, MSG_DONTWAIT);

    // Zu Nicht blockierter zurückkehren
    socket_set_nonblock($sock);

    if ($bytes === false || $bytes === 0) {
        // Kunden getrennt
        echo "Client disconnected.\n";
        socket_close($sock);
        unset($clients[$index]);
        continue;
    }

    // Ausgabedaten
    echo "Received: " . trim($buffer) . "\n";

    // Probenantwort
    $response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello from server!\n";
    socket_write($sock, $response);
}

// Geringfügige Verzögerungsvermeidung CPU Voll
usleep(100000);

}

Socket_close ($ server);
?>
</code>

Verwenden Sie die Szenariobeschreibung

Im obigen Code ist unser Hörbuchsen ($ server) nicht blockiert und blockiert daher nicht auf Socket_accept () . Immer wenn eine neue Verbindung akzeptiert wird, setzen wir den neuen Kunden auch auf nicht blockierende. In dem Teil, in dem wir die Empfangsdaten verarbeiten, wechseln wir jedoch aktiv den Client -Socket in den Blockierungsmodus, da wir sicherstellen möchten, dass Socket_Recv () die von uns erwarteten Daten vollständig empfangen und Daten unvollständig vermeiden kann.

Dies ist eine sehr häufige Methode für gemischte Verwendung und ist besonders wichtig in vielen Szenarien (wie der Protokollhandshake -Phase). Sie haben beispielsweise ein einfaches Protokoll entworfen, das feststellt, dass der Client zum ersten Mal feste Headerinformationen enthalten muss, und der Server muss es vollständig empfangen, bevor er fortgesetzt wird. Zu diesem Zeitpunkt wird die Verwendung des Blockierens von Blockieren sehr bedeutungsvoll.

Dinge zu beachten

  • Seien Sie vorsichtig, wenn Sie Modi wechseln : Verwenden der Blockierung vorübergehend in nicht blockierenden Prozessen ist eine "erzwungene Wartezeit" -Methode. Obwohl es bequem ist, bleibt der Server festgefahren, wenn der Client keine Daten sendet. Es wird empfohlen, den Zeitüberschreitungsmechanismus oder die voreingestellte Datenlänge zu entsprechen.

  • Geeignet für die kurzfristige Blockierung : Diese Art des Modusumschusses eignet sich für Situationen, in denen bestimmte Vorgänge blockiert werden müssen, und es wird nicht empfohlen, die Blockierung während des gesamten Kommunikationsprozesses zu verwenden.

Abschluss

Verwenden Sie Socket_Set_Block () und socket_set_nonblock (), um Ihre PHP -Socket -Programmierung flexibler zu gestalten. Sie können den entsprechenden Blockierungsmodus entsprechend der Verarbeitungslogik flexibel auswählen, wodurch Effizienz und Integrität berücksichtigt werden.

Weitere Socket -Programmierpraktiken und Beispiele finden Sie in der Dokumentation oder besuchen Sie unsere Ressourcenplattform:

https://gitbox.net/php-socket-guide