Position actuelle: Accueil> Derniers articles> Quels sont les conseils et les précautions lors de l'utilisation de socket_set_blocking et socket_get_status?

Quels sont les conseils et les précautions lors de l'utilisation de socket_set_blocking et socket_get_status?

gitbox 2025-09-12

1. Le rôle et l'utilisation de socket_set_blocking ()

La fonction socket_set_blocking () est utilisée pour définir si le socket est en mode de blocage. En mode blocage, les opérations de lecture et d'écriture du socket attendront que les données soient prêtes; Au lieu de bloquer le mode, s'il n'y a pas de données, l'opération reviendra immédiatement au lieu d'attendre que les données arrivent. Ceci est particulièrement important pour les serveurs qui doivent gérer plusieurs connexions client, et le mode non bloquant peut empêcher l'ensemble du programme de suspendre en raison du blocage d'une connexion.

 <span><span><span class="hljs-keyword">bool</span></span><span> </span><span><span class="hljs-title function_ invoke__">socket_set_blocking</span></span><span> ( resource </span><span><span class="hljs-variable">$socket</span></span><span> , </span><span><span class="hljs-keyword">bool</span></span><span> </span><span><span class="hljs-variable">$blocking</span></span><span> )
</span></span>
  • $ socket : ressource de socket.

  • $ Blocking : Si vrai , la prise est en mode de blocage; Si faux , la prise est en mode non bloquant.

Par exemple, définissez une prise sur le mode non bloquant:

 <span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_create</span></span><span>(AF_INET, SOCK_STREAM, SOL_TCP);
</span><span><span class="hljs-title function_ invoke__">socket_set_blocking</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-literal">false</span></span><span>);
</span></span>

2. Le rôle et l'utilisation de socket_get_status ()

La fonction socket_get_status () est utilisée pour obtenir les informations d'état de la prise actuelle, y compris si elle est en mode de blocage, si la prise a été fermée, etc. Renvoie un tableau associatif contenant les champs suivants:

  • Bloqué : s'il est en mode de blocage, 1 signifie bloquer et 0 signifie non bloquant.

  • EOF : si l'indicateur de fin du fichier a été atteint (pour le cas où la connexion est fermée).

  • Erreur : le code d'erreur de la prise actuelle.

  • ERRORSTR : Message d'erreur pour la prise actuelle.

 <span><span><span class="hljs-keyword">array</span></span><span> </span><span><span class="hljs-title function_ invoke__">socket_get_status</span></span><span> ( resource </span><span><span class="hljs-variable">$socket</span></span><span> )
</span></span>

Un exemple, obtenez le statut d'une prise:

 <span><span><span class="hljs-variable">$status</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_get_status</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Blocked: "</span></span><span> . </span><span><span class="hljs-variable">$status</span></span><span>[</span><span><span class="hljs-string">'blocked'</span></span><span>] . </span><span><span class="hljs-string">"\n"</span></span><span>;
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"EOF: "</span></span><span> . </span><span><span class="hljs-variable">$status</span></span><span>[</span><span><span class="hljs-string">'eof'</span></span><span>] . </span><span><span class="hljs-string">"\n"</span></span><span>;
</span></span>

3. Conseils et précautions combinées

La combinaison de socket_set_blocking () et socket_get_status () peut obtenir une communication réseau plus flexible et efficace, en particulier lors de la gestion des connexions simultanées. Voici quelques conseils et précautions lorsque vous utilisez:

(1) Définir et confirmer le mode de blocage

Dans certains cas, nous devons changer dynamiquement le mode de blocage de la prise. Par exemple, lors du traitement d'une demande de réseau, si les données de lecture de socket sont en mode de blocage, lorsque le réseau n'est pas en bon état ou que les données ne sont pas prêtes, l'ensemble du programme peut être suspendu. À l'heure actuelle, vous pouvez passer en mode non bloquant via socket_set_blocking () , puis vérifier l'état du socket via socket_get_status () pour éviter le blocage.

Par exemple:

 <span><span><span class="hljs-title function_ invoke__">socket_set_blocking</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-literal">false</span></span><span>);
</span><span><span class="hljs-variable">$status</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_get_status</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$status</span></span><span>[</span><span><span class="hljs-string">'blocked'</span></span><span>] == </span><span><span class="hljs-number">0</span></span><span>) {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Les prises sont maintenant en mode non bloquant。\n"</span></span><span>;
}
</span></span>
(2) Optimisation des performances en mode non bloquant

Lorsque la prise est en mode non bloquant, des fonctions telles que socket_read () seront renvoyées immédiatement, même s'il n'y a pas de données à lire. Pour éviter les appels sans signification répétés, socket_get_status () peut être combiné avec socket_get_status () pour déterminer si le socket actuel a lu les données ou s'il a atteint EOF (fin du fichier).

 <span><span><span class="hljs-variable">$data</span></span><span> = </span><span><span class="hljs-string">''</span></span><span>;
</span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-literal">true</span></span><span>) {
    </span><span><span class="hljs-variable">$status</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_get_status</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$status</span></span><span>[</span><span><span class="hljs-string">'eof'</span></span><span>]) {
        </span><span><span class="hljs-keyword">break</span></span><span>; </span><span><span class="hljs-comment">// Aucune donnée à lire</span></span><span>
    }
    </span><span><span class="hljs-variable">$buffer</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_read</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-number">1024</span></span><span>);
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$buffer</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
        </span><span><span class="hljs-comment">// Gérer les erreurs de lecture</span></span><span>
        </span><span><span class="hljs-keyword">break</span></span><span>;
    }
    </span><span><span class="hljs-variable">$data</span></span><span> .= </span><span><span class="hljs-variable">$buffer</span></span><span>;
}
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Lire les données: <span class="hljs-subst">$data</span></span></span><span>\n";
</span></span>

Grâce au code ci-dessus, nous pouvons juger si l'EOF est atteint en temps réel et éviter les lectures répétées inutiles.

(3) Utilisez socket_get_status () pour vérifier l'état de la connexion

socket_get_status () vérifie non seulement l'état de blocage, mais nous aide également à comprendre d'autres informations importantes sur la prise. Par exemple, il peut être utilisé pour déterminer si la prise a été fermée (indicateur EOF) ou si une erreur s'est produite.

 <span><span><span class="hljs-variable">$status</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_get_status</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$status</span></span><span>[</span><span><span class="hljs-string">'eof'</span></span><span>]) {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"La connexion est fermée。\n"</span></span><span>;
}
</span></span>
(4) N'appelez pas fréquemment socket_get_status ()

Bien que socket_get_status () puisse obtenir l'état du socket en temps réel, appeler cette fonction trop fréquemment peut conduire à des frais généraux de performances. Par conséquent, dans un environnement de concurrence élevé, la fréquence d'appel est raisonnablement contrôlée pour éviter les contrôles d'état inutiles.

(5) Gestion des exceptions et vérification des erreurs

Lorsque vous utilisez ces deux fonctions, en particulier lors de l'exécution des opérations de socket (telles que socket_read () ), la gestion des erreurs doit être effectuée. Les opérations de socket peuvent échouer en raison de problèmes de réseau ou d'autres raisons, donc une logique de traitement des erreurs appropriée doit être ajoutée lors de l'utilisation réellement.

 <span><span><span class="hljs-variable">$buffer</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_read</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-number">1024</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$buffer</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
    </span><span><span class="hljs-variable">$error_code</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_last_error</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Erreur de lecture: "</span></span><span> . </span><span><span class="hljs-title function_ invoke__">socket_strerror</span></span><span>(</span><span><span class="hljs-variable">$error_code</span></span><span>) . </span><span><span class="hljs-string">"\n"</span></span><span>;
}
</span></span>

4. Résumé

L'utilisation de socket_set_blocking () et socket_get_status () peut contrôler et obtenir efficacement les informations d'état de socket pour éviter les goulots d'étranglement des performances causés par le blocage. Dans le développement réel, en définissant raisonnablement le mode de blocage et en jugeant l'EOF et l'état d'erreur, la vitesse de réponse et la robustesse du programme peuvent être améliorées. Cependant, il convient de noter que les fonctions fréquentes d'appel pour indiquer peuvent avoir un impact sur les performances, de sorte que la vérification doit être effectuée aux moments appropriés pour éviter les appels excessifs.

L'utilisation de ces deux fonctions peut raisonnablement améliorer considérablement la flexibilité et l'efficacité de la manipulation des connexions simultanées, ce qui rend les applications de communication de réseau PHP plus stables et plus efficaces.