Lors de la programmation de socket avec PHP, socket_accept () est une fonction clé qui accepte une connexion client qui a été connectée à la prise d'écoute. Cependant, pendant le développement réel, vous pouvez rencontrer des situations où socket_accept () ne peut pas recevoir de connexions. Ce type de problème est souvent déroutant. Cet article énumèrera cinq causes courantes d'erreurs et fournira des solutions correspondantes pour vous aider à localiser et résoudre rapidement des problèmes.
Description du problème:
Après avoir créé le socket et lié l'adresse, si socket_listeten () n'est pas appelé, le socket ne commencera pas à écouter les demandes de connexion, et socket_accept () ne réussira jamais.
Solution:
Assurez-vous d'appeler socket_listten () avant d'appeler socket_accept () :
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 12345);
socket_listen($socket); // essentiel
$client = socket_accept($socket);
Description du problème:
Si le port que vous liez a été occupé par d'autres programmes, socket_bind () échouera, ce qui entraînera des erreurs dans toutes les opérations suivantes, y compris socket_accept () .
Solution:
Pour vérifier si le port est occupé, vous pouvez utiliser des commandes telles que netstat -tlnp | Grep 12345 . Vérifiez également la valeur de retour de socket_bind () et utilisez socket_last_error () pour obtenir le message d'erreur:
if (!socket_bind($socket, '0.0.0.0', 12345)) {
echo "La reliure a échoué: " . socket_strerror(socket_last_error($socket));
exit;
}
Description du problème:
Lorsque le serveur attend la connexion, le client n'essaie pas du tout de se connecter, ou se connecte à la mauvaise adresse et au port, donc naturellement il ne peut pas déclencher socket_accept () .
Solution:
Confirmez si l'adresse de connexion et le port du client sont corrects, par exemple:
$client = stream_socket_client("tcp://m66.net:12345", $errno, $errstr, 30);
Vous pouvez également utiliser Telnet M66.net 12345 pour tester manuellement si la connexion peut réussir.
Description du problème:
socket_accept () est une fonction de blocage qui l'attendra s'il n'y a pas de connexion client. Cela peut donner au programme que c'est coincé.
Solution:
Vous pouvez utiliser socket_set_nonblock () pour définir la prise d'écoute en mode non bloquant, ou utiliser socket_select () pour implémenter le délai d'attente:
socket_set_nonblock($socket);
$client = @socket_accept($socket);
if ($client === false) {
echo "Aucune demande de connexion actuellement\n";
}
ou:
$read = [$socket];
$write = $except = [];
if (socket_select($read, $write, $except, 5) > 0) {
$client = socket_accept($socket);
}
Description du problème:
Bien que le port d'écoute du serveur soit correctement défini, les règles de pare-feu du système d'exploitation ou la stratégie de groupe de sécurité du serveur Cloud empêchent les demandes de connexion client.
Solution:
Vérifiez et ouvrez le port du serveur. Par exemple, l'utilisation d'iPtables ou de Firewalld sur Linux permet d'accéder au port 12345, ou d'ouvrir des ports correspondants dans des plates-formes de service cloud telles que AWS et Alibaba Cloud.