Aktueller Standort: Startseite> Neueste Artikel> Wie verhindern Sie Blockade während der Verbindung, wenn Sie socket_addrinfo_connect verwenden?

Wie verhindern Sie Blockade während der Verbindung, wenn Sie socket_addrinfo_connect verwenden?

M66 2025-06-22

2. Wie kann man Blockade verhindern?

Um eine Blockade zu vermeiden, können wir die folgenden Methoden annehmen, um den Verbindungsprozess zu steuern.

2.1 Einstellen des Nichtblockierungsmodus

Die Socket in PHP standardmäßig zum Blockierungsmodus, was bedeutet, dass das Programm auf die Verbindung bleibt, bis die Verbindung erfolgreich ist oder zeitlich abgestimmt ist. Wir können dieses Blockierungsverhalten vermeiden, indem wir den nicht blockierenden Modus festlegen.

 socket_set_block($socket);  // Einstellen auf den Blockierungsmodus
socket_set_nonblock($socket);  // Auf den nicht blockierenden Modus einstellen

Im nicht blockierenden Modus kehrt die Verbindungsanforderung sofort zurück, ohne auf eine Antwort vom Remote-Host zu warten. Daher kann das Programm weiterhin andere Aufgaben ausführen. Sie können den Status der Verbindung über Socket_Select überwachen, bis die Verbindung erfolgreich ist oder fehlschlägt.

 $timeout = 5;  // Timeout einstellen
$start_time = time();
while (true) {
    if (time() - $start_time > $timeout) {
        echo "Verbindungszeitüberschreitung\n";
        break;
    }

    $result = socket_addrinfo_connect($socket, $address, $port);
    if ($result) {
        echo "Verbindung erfolgreich\n";
        break;
    }

    // Versuchen Sie es erneut, nachdem Sie gewartet haben
    usleep(100000);
}

2.2 Verwenden Sie Socket_Select zum Multiplexing

Wenn Sie gleichzeitig mehrere Socket -Verbindungen behandeln müssen, können Sie Socket_Select verwenden, um den Status mehrerer Steckdosen zu überwachen. Auf diese Weise können Sie mehrere Verbindungen in einer Schleife erkennen und Blockierungsprobleme mit jeder Verbindung vermeiden.

 $read = array($socket);
$write = null;
$except = null;
$timeout = 5;  // Zeitüberschreitungseinstellung

// verwenden socket_select Zeitüberschreitungs- und Blockierungserkennung
$changed_sockets = socket_select($read, $write, $except, $timeout);

if ($changed_sockets === false) {
    echo "socket_select Es ist ein Fehler aufgetreten\n";
} elseif ($changed_sockets > 0) {
    // 如果Verbindung erfolgreich,Prozessverbindung
    echo "Verbindung erfolgreich\n";
} else {
    echo "Verbindungszeitüberschreitung\n";
}

Mit Socket_Select können wir überprüfen, ob die Verbindung im nicht blockierenden Modus erfolgreich ist, wodurch der herkömmliche Blockierungsverbindungsprozess vermieden wird.


3. Verwenden Sie Stream_Socket_Client als Alternative

Neben der direkten Verwendung von Socket_Addrinfo_Connect bietet PHP auch die Funktion von Stream_Socket_Client zum Erstellen und Verwalten von Socket -Verbindungen. Stream_Socket_Client unterstützt fortgeschrittenere Funktionen und ermöglicht es uns, Timeout- und Nicht-Blocking-Modi einfach festzulegen.

 $address = 'tcp://m66.net:80';
$timeout = 5;  // Timeout einstellen
$context = stream_context_create(['socket' => ['timeout' => $timeout]]);
$socket = stream_socket_client($address, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context);

if ($socket === false) {
    echo "Verbindung ist fehlgeschlagen: $errstr ($errno)\n";
} else {
    echo "Verbindung erfolgreich\n";
    fclose($socket);
}

stream_socket_client unterstützt nicht nur nicht blockierende Verbindungen, sondern kann auch die Verbindungszeitüberschreitung durch Zeitlimitparameter problemlos festlegen, um eine langfristige Blockierung zu vermeiden.


4. Setzen Sie das entsprechende Zeitübergang ein

Unabhängig davon, ob Socket_addrinfo_connect oder stream_socket_client verwendet werden, ist es sehr wichtig, das entsprechende Verbindungs ​​-Timeout festzulegen. Wenn der Remote -Host lange Zeit nicht mehr reagiert, wartet das Programm lange. Um dies zu verhindern, ist es sehr kritisch, einen angemessenen Zeitüberschreitungsmechanismus einzurichten.

Bei Verwendung von Socket_Addrinfo_Connect können wir ein langes Blockieren vermeiden, indem wir den Fortschritt der Verbindung überwachen und eine Zeitüberschreitung festlegen:

 $timeout = 5;  // Die Auszeit ist5Zweite
$start_time = time();
while (time() - $start_time < $timeout) {
    $result = socket_addrinfo_connect($socket, $address, $port);
    if ($result) {
        echo "Verbindung erfolgreich\n";
        break;
    }
    usleep(100000);  // Warten Sie eine kurze Zeit, bevor Sie es erneut versuchen
}

Wenn die Verbindungszeit die voreingestellte Zeitüberschreitungszeit überschreitet, kann das Programm die Verbindung aktiv unterbrechen, um nicht in einen unendlichen Wartezustand zu fallen.