Position actuelle: Accueil> Derniers articles> Notes sur l'utilisation de socket_clear_error () dans des prises non bloquantes

Notes sur l'utilisation de socket_clear_error () dans des prises non bloquantes

M66 2025-05-25

Dans la programmation du réseau PHP, les prises non bloquantes sont souvent utilisées pour améliorer la vitesse de réponse du programme et la concurrence. En définissant Socket sur le mode non bloquant, le programme ne bloquera pas en attente de données, afin que davantage de tâches puissent être traitées en même temps. Cependant, les modèles non bloquants apportent également une complexité supplémentaire, la gestion des erreurs étant particulièrement critique. Cet article se concentrera sur la façon d'utiliser correctement la fonction socket_clear_error () dans les prises non bloquantes, ainsi que sur les problèmes auxquels il faut faire attention lors de son utilisation.

Qu'est-ce que socket_clear_error ()?

socket_clear_error () est une fonction de PHP qui efface les erreurs qui se sont produites sur une prise. Il est souvent utilisé dans les scénarios de gestion des exceptions et de récupération des erreurs pour s'assurer que l'état d'erreur de socket n'affecte pas les opérations ultérieures.

Caractéristiques d'erreur du socket non bloquant

Socket non bloquant lors de l'exécution d'une opération, s'il n'y a actuellement pas de données disponibles ou si la ressource n'est pas disponible, elle reviendra immédiatement au lieu d'attendre. Ce comportement conduit souvent à certains états «d'erreur», tels que Eagain ou Ewouldblock , qui ne sont pas réellement d'erreurs réelles, mais signifie simplement que la ressource est temporairement indisponible. Dans ce cas, vous ne devez pas signaler directement une erreur ou fermer la connexion, mais attendre la prochaine fois qu'elle sera disponible.

L'heure correcte pour utiliser socket_clear_error ()

  1. Nettoyer les erreurs traitées <br> Lorsque le code d'erreur de socket est détecté, s'il est déterminé que l'erreur a été correctement traitée (par exemple, Eagain est traité et en attente de réessayer), Socket_Clear_error () doit être appelé pour réinitialiser l'état d'erreur pour éviter les erreurs résiduelles affectant les opérations suivantes.

  2. Évitez d'appeler sans erreurs <br> Il n'est pas recommandé d'appeler fréquemment socket_clear_error () sans une erreur détectée, sinon les informations d'erreur réelles peuvent être masquées, ce qui rend difficile la résolution de problèmes.

  3. Utiliser avec socket_last_error () <br> Habituellement, socket_last_error () est utilisé pour déterminer l'état d'erreur de courant de la prise. Socket_clear_error () est appelé uniquement s'il y a effectivement une erreur.

Exemple de code

 <?php
// Créer un non-bloquant Socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($socket);

// Connectez-vous au serveur
socket_connect($socket, 'm66.net', 80);

// Les données d&#39;envoi non bloquantes
$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) {
        // Les ressources sont temporairement indisponibles,Réessayer plus tard
        echo "Write would block, try again later.\n";
    } else {
        // Autres erreurs,Message d&#39;erreur de sortie et statut d&#39;erreur effacer
        echo "Socket write error: " . socket_strerror($errCode) . "\n";
        socket_clear_error($socket);
    }
}

// Lisez la réponse
while (true) {
    $buffer = socket_read($socket, 2048);
    if ($buffer === false) {
        $errCode = socket_last_error($socket);
        if ($errCode == SOCKET_EAGAIN || $errCode == SOCKET_EWOULDBLOCK) {
            // Les données sont temporairement indisponibles,Continuez à attendre
            usleep(100000); // 100ms
            continue;
        } else {
            echo "Socket read error: " . socket_strerror($errCode) . "\n";
            socket_clear_error($socket);
            break;
        }
    } elseif ($buffer === '') {
        // La connexion se ferme
        break;
    } else {
        echo $buffer;
    }
}

socket_close($socket);
?>

Problèmes à connaître lors de l'utilisation

  • Différencier les types d'erreurs : en mode non bloquant, les erreurs EAGain ou Ewouldblock sont normales et ne peuvent pas être traitées comme une défaillance de connexion ou un traitement d'exception.

  • Évitez la compensation fréquente des erreurs : l'état d'erreur ne doit être effacé qu'après avoir confirmé qu'il a été correctement géré, et les appels aveugles couvriront le vrai problème.

  • Combiné avec d'autres fonctions pour surveiller le statut : par exemple, socket_last_error () est utilisé en combinaison avec socket_clear_error () pour gérer les erreurs plus en toute sécurité.

  • Gérer le temps mort et la logique de réessayer bien : les opérations non bloquantes nécessitent souvent une coopération avec les mécanismes d'interrogation ou d'événements pour concevoir raisonnablement l'intervalle de réessayer et le nombre de fois.