Position actuelle: Accueil> Derniers articles> Comment empêcher le blocage lors de la connexion lors de l'utilisation de socket_addrinfo_connect?

Comment empêcher le blocage lors de la connexion lors de l'utilisation de socket_addrinfo_connect?

M66 2025-06-22

2. Comment empêcher le blocage?

Pour éviter le blocage, nous pouvons prendre les méthodes suivantes pour contrôler le processus de connexion.

2.1 Réglage du mode non bloquant

Le socket de PHP par défaut en mode de blocage, ce qui signifie que le programme se décroche en attendant la connexion jusqu'à ce que la connexion soit réussie ou chronométrée. Nous pouvons éviter ce comportement de blocage en définissant le mode non bloquant.

 socket_set_block($socket);  // Défini sur le mode de blocage
socket_set_nonblock($socket);  // Réglé sur le mode non bloquant

En mode non bloquant, la demande de connexion renvoie immédiatement sans attendre de réponse de l'hôte distant. Par conséquent, le programme peut continuer à effectuer d'autres tâches. Vous pouvez surveiller l'état de la connexion via socket_select jusqu'à ce que la connexion réussit ou échoue.

 $timeout = 5;  // Définir le délai
$start_time = time();
while (true) {
    if (time() - $start_time > $timeout) {
        echo "Délai de connexion\n";
        break;
    }

    $result = socket_addrinfo_connect($socket, $address, $port);
    if ($result) {
        echo "Connexion avec succès\n";
        break;
    }

    // Réessayer après avoir attendu
    usleep(100000);
}

2.2 Utilisez Socket_Select pour le multiplexage

Si vous devez gérer plusieurs connexions de socket en même temps, vous pouvez utiliser Socket_Select pour surveiller l'état de plusieurs sockets. Cela vous permet de détecter plusieurs connexions dans une boucle, en évitant de bloquer les problèmes avec chaque connexion.

 $read = array($socket);
$write = null;
$except = null;
$timeout = 5;  // Délai d'expiration

// utiliser socket_select Délai et détection de blocage
$changed_sockets = socket_select($read, $write, $except, $timeout);

if ($changed_sockets === false) {
    echo "socket_select Une erreur s'est produite\n";
} elseif ($changed_sockets > 0) {
    // 如果Connexion avec succès,Connexion de traitement
    echo "Connexion avec succès\n";
} else {
    echo "Délai de connexion\n";
}

Avec Socket_Select, nous pouvons vérifier si la connexion réussit en mode non bloquant, évitant ainsi le processus de connexion de blocage traditionnel.


3. Utilisez Stream_Socket_Client comme alternative

En plus d'utiliser Socket_Addrinfo_Connect directement, PHP fournit également la fonction Stream_Socket_Client pour créer et gérer les connexions de socket. Stream_Socket_Client prend en charge des fonctionnalités plus avancées et nous permet de définir facilement des modes de délai d'attente et de non-blocage.

 $address = 'tcp://m66.net:80';
$timeout = 5;  // Définir le délai
$context = stream_context_create(['socket' => ['timeout' => $timeout]]);
$socket = stream_socket_client($address, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context);

if ($socket === false) {
    echo "Échec de la connexion: $errstr ($errno)\n";
} else {
    echo "Connexion avec succès\n";
    fclose($socket);
}

Stream_Socket_Client prend non seulement des connexions non bloquantes, mais peut également facilement définir les paramètres de délai d'expiration de la connexion pour éviter le blocage à long terme.


4. Réglez le délai d'expiration approprié

Que ce soit en utilisant socket_addrinfo_connect ou stream_socket_client , il est très important de définir le délai de connexion approprié. Si l'hôte distant ne répond pas longtemps, le programme attendra longtemps. Pour éviter cela, la mise en place d'un mécanisme d'expiration raisonnable est très critique.

Lorsque vous utilisez socket_addrinfo_connect , nous pouvons éviter le blocage long en surveillant la progression de la connexion et en définissant un délai d'expiration:

 $timeout = 5;  // Le délai d'attente est5Deuxième
$start_time = time();
while (time() - $start_time < $timeout) {
    $result = socket_addrinfo_connect($socket, $address, $port);
    if ($result) {
        echo "Connexion avec succès\n";
        break;
    }
    usleep(100000);  // Attendez un court moment avant de réessayer
}

Si le temps de connexion dépasse l'heure du délai d'expiration prédéfini, le programme peut interrompre activement la connexion pour éviter de tomber dans un état d'attente infini.