Position actuelle: Accueil> Derniers articles> Comment définir le délai de lecture dans la fonction Stream_Socket_RecvFrom pour éviter le blocage à long terme du programme?

Comment définir le délai de lecture dans la fonction Stream_Socket_RecvFrom pour éviter le blocage à long terme du programme?

M66 2025-06-22

Lorsque vous utilisez PHP pour la programmation réseau, la fonction Stream_Socket_RecVFrom est une fonction couramment utilisée pour recevoir des paquets UDP. Cependant, par défaut, cette fonction bloque en attendant les données jusqu'à ce que les données soient reçues ou une erreur se produit, ce qui, dans certains scénarios, peut provoquer des pauses à long terme au programme, affectant les performances et l'expérience utilisateur. Pour éviter ce long blocage, nous devons définir un temps mort en lecture.

Cet article expliquera en détail comment définir un délai d'expiration de lecture dans la fonction Stream_Socket_RecvFrom pour vous aider à mieux contrôler le comportement du programme.


1. Introduction à stream_socket_recvfrom

L'utilisation de base de la fonction Stream_Socket_RecvFrom est la suivante:

 $data = stream_socket_recvfrom($socket, 1024);

Il lira jusqu'à 1024 octets de données de la prise $ spécifiée. Si aucune donnée n'arrive, la fonction bloque et attend.


2. Bloquer des problèmes et la nécessité de paramètres d'expiration

Lorsque Stream_Socket_RecvFrom est appelé, si le pair n'envoie pas de données pendant longtemps, le programme attendra, ce qui est très défavorable pour la vitesse de réponse et la stabilité des applications réseau. Afin d'éviter que le programme soit bloqué pendant longtemps, nous devons définir un mécanisme de délai d'expiration, et une fois le délai d'expiration, nous abandonnerons la lecture et effectuerons d'autres traitements.


3. Comment définir le délai de lecture

Dans PHP, le délai d'expiration du flux d'opération est généralement implémenté via la fonction Stream_Set_timeout . Cette fonction peut définir un temps d'attente pour un flux ouvert.

Exemple:

 // créer UDP socket
$socket = stream_socket_server("udp://0.0.0.0:9999", $errno, $errstr, STREAM_SERVER_BIND);

if (!$socket) {
    die("无法créersocket: $errstr ($errno)\n");
}

// Définir le délai,Unités en secondes et microsecondes
// 这里Définir le délai时间为 5 Deuxième
stream_set_timeout($socket, 5);

// Appeler une fonction de lecture
$data = stream_socket_recvfrom($socket, 1024);

$info = stream_get_meta_data($socket);
if ($info['timed_out']) {
    echo "Lire le délai d'expiration des données,Abandonner\n";
} else {
    echo "Données reçues: $data\n";
}
  • stream_set_timeout ($ socket, 5) définit un délai d'expiration de 5 secondes.

  • Après avoir lu les données, déterminez si le délai d'attente est réalisé par Stream_get_Meta_Data ($ socket) .


4. Utilisez le mode non bloquant en conjonction avec le sondage

En plus du mécanisme de délai d'expiration, une autre pratique courante consiste à définir la prise sur le mode non bloquant, puis à lire les données conjointement avec un mécanisme de sondage ou de l'événement.

 // créer socket
$socket = stream_socket_server("udp://0.0.0.0:9999", $errno, $errstr, STREAM_SERVER_BIND);

if (!$socket) {
    die("无法créersocket: $errstr ($errno)\n");
}

// Définir le mode non bloquant
stream_set_blocking($socket, false);

$startTime = time();
$timeout = 5; // Deuxième

while (true) {
    $data = stream_socket_recvfrom($socket, 1024);
    if ($data !== false && $data !== '') {
        echo "Données reçues: $data\n";
        break;
    }
    
    if (time() - $startTime > $timeout) {
        echo "Lire le délai d'attente,Quitter la boucle\n";
        break;
    }
    
    // éviterCPUOccupation trop élevée,Dormir de manière appropriée
    usleep(100000); // 100毫Deuxième
}

Cette méthode permet un contrôle plus flexible de la logique de lecture et facilite l'intégration des boucles d'événements.


5. Résumé

  • Stream_Socket_RecvFrom Blocks par défaut, ce qui peut faire attendre le programme pendant longtemps.

  • Utilisez Stream_Set_timeout pour définir l'heure du délai d'expiration pour éviter le blocage trop longtemps.

  • Après avoir lu, utilisez Stream_get_Meta_Data pour déterminer si le délai d'attente est atteint.

  • Vous pouvez également utiliser le mode non bloquant pour contrôler la durée de lecture avec le sondage.

La définition raisonnable de paramètres de délai d'attente est la clé pour assurer une réponse stable des programmes réseau.