Bei der PHP-Netzwerkprogrammierung werden häufig nicht blockierende Sockets verwendet, um die Programmreaktionsgeschwindigkeit und -vergleiche zu verbessern. Durch Einstellen von Socket in den Nicht-Blocking-Modus wird das Programm aufgrund des Wartens auf Daten nicht blockiert, damit gleichzeitig weitere Aufgaben bearbeitet werden können. Nicht blockierende Muster bringen jedoch auch eine zusätzliche Komplexität, wobei die Fehlerbehandlung besonders kritisch ist. Dieser Artikel konzentriert sich darauf, wie die Funktion socket_clear_error () in nicht blockierenden Sockets sowie Probleme, die bei der Verwendung geachtet werden müssen, korrekt verwendet werden.
Socket_Clear_error () ist eine Funktion in PHP, die Fehler auf einem Socket löscht. Es wird häufig in Ausnahmebehandlung und Fehlerwiederherstellungsszenarien verwendet, um sicherzustellen, dass der Socket -Fehlerstatus die nachfolgenden Operationen nicht beeinflusst.
Nicht blockierende Socket Bei der Durchführung eines Betriebs, wenn derzeit keine verfügbaren Daten vorhanden sind oder die Ressource nicht verfügbar ist, wird sofort zurückgegeben, anstatt zu warten. Dieses Verhalten führt häufig zu bestimmten "Fehler" -Staaten wie Eagain oder eWlouldblock , die eigentlich keine wirklichen Fehler sind, sondern einfach, dass die Ressource vorübergehend nicht verfügbar ist. In diesem Fall sollten Sie keinen Fehler direkt melden oder die Verbindung schließen, sondern darauf warten, dass das nächste Mal verfügbar ist.
Reinigen Sie verarbeitete Fehler <br> Wenn der Socket -Fehlercode erkannt wird und festgestellt wird, dass der Fehler korrekt verarbeitet wurde (z. B. Eagain wird verarbeitet und auf Wiederholung wartet), sollte Socket_Clear_error () aufgerufen werden, um den Fehlerzustand zurückzusetzen, um Restfehler zu vermeiden, die nachfolgende Operationen betreffen.
Vermeiden Sie es, ohne Fehler aufzurufen <br> Es wird nicht empfohlen, ohne festgestellte Fehler häufig auf Socket_Clear_error () aufzurufen. Andernfalls können die tatsächlichen Fehlerinformationen maskiert werden, was es schwierig macht, Probleme zu beheben.
Verwendung mit socket_last_error () <br> Normalerweise wird Socket_Last_error () verwendet, um den aktuellen Fehlerstatus des Socket zu bestimmen. Socket_Clear_error () wird nur aufgerufen, wenn tatsächlich ein Fehler vorliegt.
<?php
// Erstellen Sie eine Nichtblockierung Socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($socket);
// Stellen Sie eine Verbindung zum Server her
socket_connect($socket, 'm66.net', 80);
// Nicht blockierende Sendedaten
$data = "GET / HTTP/1.1\r\nHost: m66.net\r\nConnection: Close\r\n\r\n";
$bytesSent = socket_write($socket, $data);
if ($bytesSent === false) {
$errCode = socket_last_error($socket);
if ($errCode == SOCKET_EAGAIN || $errCode == SOCKET_EWOULDBLOCK) {
// Ressourcen sind vorübergehend nicht verfügbar,Versuchen Sie es später erneut
echo "Write would block, try again later.\n";
} else {
// Andere Fehler,Ausgabefehlermeldung und Löschen des Fehlerstatus
echo "Socket write error: " . socket_strerror($errCode) . "\n";
socket_clear_error($socket);
}
}
// Lesen Sie die Antwort
while (true) {
$buffer = socket_read($socket, 2048);
if ($buffer === false) {
$errCode = socket_last_error($socket);
if ($errCode == SOCKET_EAGAIN || $errCode == SOCKET_EWOULDBLOCK) {
// Daten sind vorübergehend nicht verfügbar,Warten Sie weiter
usleep(100000); // 100ms
continue;
} else {
echo "Socket read error: " . socket_strerror($errCode) . "\n";
socket_clear_error($socket);
break;
}
} elseif ($buffer === '') {
// Verbindung schließt
break;
} else {
echo $buffer;
}
}
socket_close($socket);
?>
Differenzierung von Fehlertypen : Im Nicht-Blocking-Modus sind Eagain oder EWOuldBlock- Fehler normal und können nicht als Verbindungsfehler oder Ausnahmebereich behandelt werden.
Vermeiden Sie häufige Löschen von Fehlern : Der Fehlerstatus sollte erst gelöscht werden, nachdem bestätigt wurde, dass er ordnungsgemäß behandelt wurde, und blinde Anrufe werden das eigentliche Problem abdecken.
In Kombination mit anderen Funktionen zur Überwachung des Status wird beispielsweise Socket_Last_error () in Kombination mit Socket_Clear_error () verwendet, um Fehler sicherer zu verwalten.
Timeout- und Wiederholungslogik gut handhaben : Nicht blockierende Operationen erfordern häufig eine Zusammenarbeit mit Umfragen oder Ereignismechanismen, um das Wiederholungsintervall und die Anzahl der Male vernünftig zu gestalten.