Bei der Programmierung von Netzwerken mit PHP sind Socket_Set_Block () und Socket_Set_Nonblock () zwei sehr wichtige Funktionen, die steuern, ob der Socket im Blockier- oder Nicht-Blocking-Modus funktioniert. Ein vernünftiges Umschalten dieser beiden Modi kann uns dabei helfen, die Netzwerk -E/A -E/A flexibler zu behandeln und die Programmeffizienz und -reaktionsfähigkeit zu verbessern.
Blockierungsmodus (Standard): In diesem Modus warten Socket -Operationen (wie Socket_read () , Socket_accept () usw.), bis die Daten lesbar sind oder die Verbindung abgeschlossen ist. Diese Methode ist einfach zu schreiben, aber in hohen Parallelitätsszenarien kann sie Thread- oder Prozessblockade verursachen und die Gesamtleistung verringern.
Nicht-Blocking-Modus: Umgekehrt kehrt Socket-Operationen im Nicht-Blocking-Modus sofort zurück. Wenn die Operation nicht sofort abgeschlossen werden kann (wenn keine Daten gelesen werden), gibt die Funktion FALSE zurück und legt den Fehlercode auf Eagain oder EWOLDBLOCK fest.
Hier ist ein einfaches Beispiel, das zeigt, wie man zwischen Blockier- und Nichtblockierungszuständen von Steckdosen wechselt und sie in Kombination mit Anwendungsszenarien verwendet:
<?php
$host = 'gitbox.net';
$port = 8080;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
die("socket_create() failed: " . socket_strerror(socket_last_error()));
}
// Auf den nicht blockierenden Modus einstellen,Versuchen Sie zu verbinden
socket_set_nonblock($socket);
$connected = @socket_connect($socket, $host, $port);
if (!$connected) {
$err = socket_last_error($socket);
if ($err !== SOCKET_EINPROGRESS && $err !== SOCKET_EALREADY) {
die("socket_connect() failed: " . socket_strerror($err));
}
}
// verwenden select Überprüfen Sie, ob die Verbindung erfolgreich ist
$write = [$socket];
$null = [];
if (socket_select($null, $write, $null, 5) > 0) {
// Wechseln Sie zurück in den Blockierungsmodus,Wird für die nachfolgende Datenübertragung und -empfang verwendet
socket_set_block($socket);
// Senden und Empfangen von Daten
socket_write($socket, "GET / HTTP/1.1\r\nHost: $host\r\n\r\n");
$response = socket_read($socket, 2048);
echo "Response: " . $response;
} else {
die("Connection timeout or failed");
}
socket_close($socket);
?>
Nicht blockierende Verbindung : Verwenden Sie Socket_Set_NonBlock (), um zu verhindern, dass Verbindungsvorgänge die Programmausführung blockieren.
Verwenden Sie Socket_Select () , um zu warten, bis der Socket beschreibbar ist : Dies ist ein häufiger Trick, um festzustellen, ob die Verbindung erfolgreich ist.
Wechseln Sie zurück in den Blockierungsmodus : Verwenden Sie Socket_Set_Block () , um den Blockierungsmodus unmittelbar nachdem die Verbindung hergestellt wurde, um die nachfolgende Dateninteraktion zu erleichtern.
Antwort senden und readieren : Der Socket funktioniert zu diesem Zeitpunkt im Blockierungsmodus, was das Lesen der vollständigen Serverantwort erleichtert.
Verwenden Sie den nicht blockierenden Modus, wenn mehrere Verbindungsanforderungen schnell eingeleitet werden müssen.
Es ist notwendig, sicherzustellen, dass eine bestimmte Operation nicht unendlich wartet, z. B. die Zeitlimitsteuerung.
Wechseln Sie nach Abschluss einer Verbindung oder einer bestimmten Phase zurück in den Blockierungsmodus, um die Code -Verarbeitungslogik zu vereinfachen.
Im nicht blockierenden Modus müssen alle Socket-Operationen eine Fehlerprüfung durchlaufen.
Socket_Select () ist ein Schlüsselwerkzeug für die nicht blockierende Socket-Programmierung.
Der Schaltmodus sollte entsprechend der Betriebsstufe durchgeführt werden, anstatt statisch zu sein.
Durch ein vernünftiges Umschalten von Blockier- und nicht blockierenden Modi kann die PHP-Socket-Programmierung nicht nur Leistung und Stabilität berücksichtigen, sondern auch besser auf komplexe Netzwerkkommunikationsanforderungen reagieren.