Position actuelle: Accueil> Derniers articles> Quels problèmes entraîneront l'oublier de post-processus le mécanisme de délai d'expiration dans socket_set_block?

Quels problèmes entraîneront l'oublier de post-processus le mécanisme de délai d'expiration dans socket_set_block?

gitbox 2025-05-29

Lorsque vous utilisez des sockets pour la programmation réseau dans PHP, socket_set_block () et socket_set_nonblock () sont deux fonctions très importantes qui contrôlent respectivement les prises de blocage et le mode non bloquant respectivement. Mais de nombreux développeurs ignorent un point clé après l'avoir réglé sur le mode de blocage:.

Alors la question est, que se passe-t-il si vous utilisez socket_set_block () mais oubliez de définir le délai d'expiration? Le programme sera-t-il bloqué? Cet article répondra en détail à cette question.

Comportement du mode de blocage

Lorsque vous utilisez socket_set_block ($ socket) pour définir le socket sur le mode de blocage, les opérations de lecture et d'écriture suivantes (telles que socket_read () , socket_recv () , socket_write () , etc.) bloqueront et attendent lorsque les données ne seront pas prêtes. Autrement dit, si vous essayez de lire une prise sans aucune donnée, le programme s'arrêtera à cette ligne de code jusqu'à ce que les données soient lisibles ou que la connexion soit déconnectée .

Ceci est utile dans certains scénarios où une "communication simultanée" est attendue. Mais une fois que le serveur externe répond lentement, voire en permanence, insensible (comme le temps d'arrêt du serveur cible, le blocage du réseau, le blocage par pare-feu, etc.), votre programme y sera bloqué et ne peut exécuter aucun code ultérieur .

Jetons un coup d'œil à un exemple:

<code> $ socket = socket_create (af_inet, sock_stream, sol_tcp); socket_set_block ($ socket); socket_connect ($ socket, 'gitbox.net', 80); socket_write ($ socket, "get / http / 1.0 \ r \ nhost: gitbox.net \ r \ n \ r \ n");

$ réponse = socket_read ($ socket, 2048);
Echo $ réponse;
</code>

Si gitbox.net est inaccessible ou ne renvoie aucune donnée du tout, la ligne de code socket_read () bloquera indéfiniment et que le programme sera "coincé".

Pourquoi est-ce "coincé"

La cause profonde de "Stuck" est qu'il n'y a pas de délai de délai de délai . Le mode de blocage lui-même n'est pas un problème, le problème est que la valeur de délai d'expiration dans socket_set_option () n'est pas définie.

PHP fournit deux paramètres de délai d'expiration:

  1. Recevoir le délai

     socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ['sec'=>5, 'usec'=>0]);
    
  2. Envoyer le délai d'attente

     socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, ['sec'=>5, 'usec'=>0]);
    

Après les ajouter, même en mode blocage, les opérations de lecture et d'écriture n'attendent pas indéfiniment. Par exemple, le délai de réception est défini sur 5 secondes. Si aucune donnée n'est reçue dans les 5 secondes, socket_read () reviendra fausse et ne bloquera pas pour toujours.

Impact et suggestions réelles

Si vous oubliez de définir le délai d'expiration, il y a plusieurs conséquences potentielles:

  • Le serveur ne répond pas ou est coincé lorsqu'il est lent

  • L'utilisateur attend trop longtemps et a une très mauvaise expérience

  • Un blocage dans une tâche par lots fait que la tâche globale fait la queue ou même l'interruption.

  • Il est difficile de résoudre les problèmes, surtout lorsque le bogue ne se produit que lorsque le réseau est instable

Par conséquent, toute opération de réseau en mode blocage doit être utilisée avec un paramètre de délai d'attente clair .

en conclusion

Oui, si vous utilisez socket_set_block () et oubliez de définir le délai d'expiration, le programme peut en effet "périmé" dans certains cas. Ce n'est pas un bug dans PHP, mais un comportement de base du blocage des E / S dans la programmation réseau. L'utilisation rationnelle de socket_set_option () pour définir des délais d'attente est la clé pour garantir la robustesse et la réactivité du programme.

La meilleure pratique est: tant que vous entrez en mode de blocage, définissez immédiatement le délai d'expiration et ne comptez pas sur la fiabilité du serveur distant. Il s'agit d'une pensée fondamentale de la programmation défensive.