Aktueller Standort: Startseite> Neueste Artikel> Socket_accept () kooperiert mit socket_set_timeout, um die Verbindungszeitüberschreitungssteuerung zu implementieren

Socket_accept () kooperiert mit socket_set_timeout, um die Verbindungszeitüberschreitungssteuerung zu implementieren

M66 2025-05-28

In PHP wird bei der Programmierung mit nativen Sockets die Funktion Socket_accept () verwendet, um Client -Verbindungsanforderungen zu akzeptieren. Standardmäßig blockiert diese Funktion. Wenn es keine Clientverbindung gibt, wartet das Programm und kann nicht automatisch vorüber sind. Um zu vermeiden, dass das Programm aufgrund des Wartens auf die Verbindung festgefahren oder nicht reagiert, können wir socket_set_timeout () kombinieren, um die Timeout -Steuerung des Verbindungen zu erreichen, wodurch die Robustheit des Programms verbessert wird.

In diesem Artikel wird detailliert eingeführt, wie Sie Socket_accept () und socket_set_timeout () verwenden, um die Funktion des PHP -Verbindungs ​​-Timeout -Steuerelements zu implementieren.

1. Überprüfung des Grundwissens

  • Socket_accept ($ Socket)
    Warten auf die Blockierung der Clientverbindungsanforderung, wenn eine Verbindungsanforderung vorliegt, wird eine neue Socket -Ressource zurückgegeben, sonst wird sie blockiert.

  • SOCKKET_SET_TIMEOUT ($ Socket, $ Sekunden, $ microsesekunden)
    Legt die Zeitüberschreitungszeit für den angegebenen Socket fest. Nach dem Timeout gibt die Lese-/Schreiboperation einen Zeitüberschreitungsfehler zurück.

Es ist zu beachten, dass Socket_set_timeout () eine Zeitlimitsteuerung für Lese- und Schreibvorgänge ist und die blockierende Wartezeit von Socket_accept () nicht direkt steuern kann. Daher müssen wir mit anderen Methoden (z. B. nicht blockierender Modus oder mit Socket_Select () ) zusammenarbeiten, um eine echte Verbindungs-Wartezeit zu erreichen.

2. Implementierungsideen

  1. Stellen Sie den Hörbuchsen auf den nicht blockierenden Modus <br> ein Auf diese Weise blockieren Socket_accept () nicht. Wenn es keine Verbindungsanforderung gibt, wird FALSE sofort zurückgegeben.

  2. Verwenden Sie Loop + Verzögerung, um Timeout zu beurteilen <br> Rufen Sie Socket_accept () wiederholt in der Schleife auf. Wenn FALSE zurückgegeben wird, stellen Sie fest, ob das Zeitüberschreitungen abgestimmt sind. Wenn das Zeitüberschreitend abgestimmt ist, wird das Warten beendet.

  3. Sobald die Verbindung empfangen wurde, verwenden Sie socket_set_timeout (), um das Lese- und Schreiben von Timeout <br> festzulegen Stellen Sie sicher, dass während der nachfolgenden Datenübertragung eine Zeitüberschreitungssteuerung vorliegt.

3. Beispielcode

 <?php
$host = "0.0.0.0";
$port = 12345;
$timeoutSeconds = 10; // Maximale Wartezeitverbindungszeit

// erstellen TCP socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
    die("socket_create failed: " . socket_strerror(socket_last_error()) . "\n");
}

// Binden Sie Port
if (socket_bind($socket, $host, $port) === false) {
    die("socket_bind failed: " . socket_strerror(socket_last_error($socket)) . "\n");
}

// Hören Sie sich Port an
if (socket_listen($socket, 5) === false) {
    die("socket_listen failed: " . socket_strerror(socket_last_error($socket)) . "\n");
}

// Überwachung einrichten socket Nicht blockieren
socket_set_nonblock($socket);

$startTime = time();
$clientSocket = false;

echo "Warten auf die Kundenverbindung,Time-out:{$timeoutSeconds}Zweite\n";

while (true) {
    $clientSocket = @socket_accept($socket);
    if ($clientSocket !== false) {
        echo "Der Client ist verbunden!\n";
        break;
    }

    // Stellen Sie fest, ob die Zeitüberschreitung ist
    if ((time() - $startTime) >= $timeoutSeconds) {
        echo "Warten auf die Kundenverbindung超时。\n";
        break;
    }

    // Schlafen 100ms vermeiden CPU Zu hohe Belegung
    usleep(100000);
}

if ($clientSocket !== false) {
    // Einrichten des Kunden socket Timeout lesen und schreiben,Zum Beispiel 5 Zweite
    socket_set_option($clientSocket, SOL_SOCKET, SO_RCVTIMEO, ["sec"=>5, "usec"=>0]);
    socket_set_option($clientSocket, SOL_SOCKET, SO_SNDTIMEO, ["sec"=>5, "usec"=>0]);

    // Beispiel für das Lesen von Clientdaten
    $buf = '';
    $bytes = socket_recv($clientSocket, $buf, 2048, 0);
    if ($bytes === false) {
        echo "Daten nicht empfangen oder zeitlich abgestimmt:" . socket_strerror(socket_last_error($clientSocket)) . "\n";
    } else {
        echo "Empfangene Clientdaten:" . $buf . "\n";
    }

    socket_close($clientSocket);
}

socket_close($socket);
?>

4. Codeanalyse

  • Nicht blockierendes Hören : Verwenden Sie Socket_Set_Nonblock (), um Socket_accept () Blocking zu vermeiden, sodass wir die Zeitüberschreitungslogik anpassen können.

  • Looping, um auf die Verbindung zu warten : Jedes Mal, wenn Socket_accept () aufgerufen wird, gibt es sofort falsch zurück und bestimmt, ob die Zeitüberschreitungsbedingung erreicht ist. Wenn das Timeout nicht abläuft, warten Sie weiter.

  • Setzen Sie das Lesen und schreiben Sie Zeitleiter nach der Verbindung : Verwenden Sie Socket_Set_Option (), um das Lesen und Schreiben von Timeout für den Client -Socket festzulegen und zu schreiben, um eine dauerhafte Blockierung zu verhindern, wenn nachfolgende Daten gelesen werden.

  • usleep () CPU -Verwendung reduzieren : Vermeiden Sie leere Schleifen, die zu einer übermäßigen Nutzung von CPU führen.

5. Zusammenfassung

Durch Einstellen des Hörbuchs in nicht blockierende und kombinierte Schleifenabfragen, um die Zeit zu bestimmen, wird die Zeitlimitsteuerung von Socket_accept () Blockierungswartungsverbindung erreicht. Verwenden Sie gleichzeitig nach Erhalt der Verbindung Socket_Set_Option () , um das Lese- und Schreib -Timeout festzulegen, um die Stabilität und Sicherheit des Datenübertragungsprozesses sicherzustellen.

Diese Lösung ist einfach und praktisch und für PHP -Serverprogramme sehr geeignet, die eine manuelle Verwaltung von Socket -Verbindungszeitüberschreitungen erfordern.