Lors de la programmation du socket PHP, la fonction socket_set_block () est utilisée pour définir la prise sur le mode de blocage. Le mode de blocage signifie que des opérations telles que la lecture ( socket_read () ), write ( socket_write () ) ou recevoir une connexion ( socket_accept () ) attendra que les données soient lues, écrites ou une connexion soit entrante. Si cela n'est pas clair, l'utilisation de socket_set_block () dans certains scénarios fera que l'ensemble du script PHP "stagne", c'est-à-dire que le programme y est coincé pendant longtemps sans réponse, qui semble "suspendu".
Après avoir utilisé socket_set_block () , PHP entrera dans le mode de blocage et attendra le résultat du fonctionnement du socket. Si la ressource correspondante (telle que les données ou la connexion) ne revient pas pendant longtemps, le script PHP attendra et ne continuera pas à exécuter le code suivant.
Voici un exemple typique:
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, 'gitbox.net', 80);
socket_set_block($socket); // Défini sur le mode de blocage
// Essayez de lire les données
$response = socket_read($socket, 2048);
echo $response;
socket_close($socket);
?>
Si le serveur gitbox.net ne renvoie pas de données immédiatement ou ne répond pas du tout, socket_read () attendra et le script sera "coincé". Ce type de décalage ne lancera pas d'erreur à moins que le mécanisme de délai d'expiration ne soit déclenché, mais le délai d'expiration n'est pas défini par défaut, il peut donc attendre l'infini.
Utilisez socket_set_option () pour définir le délai d'expiration pour lire et écrire pour empêcher le blocage à long terme:
$timeout = ['sec' => 5, 'usec' => 0]; // Se présenter comme5Deuxième
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, $timeout);
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, $timeout);
Cela entraînera l'opération de blocage vers des temps de sortie et reviendra après avoir attendu une certaine période de temps, évitant que le script ne réponde pas longtemps.
Si vous ne souhaitez pas bloquer le script, vous pouvez utiliser socket_set_nonblock () à la place pour récupérer toutes les opérations de socket immédiatement:
socket_set_nonblock($socket);
Avec des boucles et usleep () , les attentes non bloquantes peuvent être simulées:
$buffer = '';
while (true) {
$chunk = @socket_read($socket, 2048);
if ($chunk === false) {
usleep(100000); // Dormir100ms
continue;
} elseif ($chunk === '') {
break; // La connexion se ferme
} else {
$buffer .= $chunk;
}
}
socket_select () peut vérifier si plusieurs sockets sont prêts à lire et à écrire, et c'est un moyen de gérer efficacement les opérations de blocage:
$read = [$socket];
$write = NULL;
$except = NULL;
$tv_sec = 5; // Attendre le plus5Deuxième
if (socket_select($read, $write, $except, $tv_sec) > 0) {
$response = socket_read($socket, 2048);
echo $response;
} else {
echo "Socket Délai d'expiration ou pas de données lisibles";
}
Socket_Select () peut déterminer si le socket a des données à lire avant de lire, en évitant d'entrer directement dans l'état de blocage.
L'utilisation de socket_set_block () n'est pas dangereuse, mais nécessite un contrôle très explicite de son contexte. Il est recommandé d'utiliser le mode non bloquant ou de définir explicitement le délai d'expiration en mode de blocage pour éviter les scripts bloqués en permanence en raison du retard du réseau et des problèmes de service non réactifs.
Pour les scénarios où une réponse en temps réel ou un traitement simultané est requis, il est recommandé d'utiliser socket_set_nonblock () ou combiné avec socket_select () pour contrôler de manière flexible le flux d'exécution du programme. Cela améliore non seulement la robustesse du programme, mais améliore également considérablement l'efficacité de la réponse du système.