Position actuelle: Accueil> Derniers articles> Quels sont les problèmes courants rencontrés lorsque Socket_Create est connecté aux hôtes distants? Comment le résoudre?

Quels sont les problèmes courants rencontrés lorsque Socket_Create est connecté aux hôtes distants? Comment le résoudre?

gitbox 2025-09-21

2. Blocage des politiques de pare-feu / réseau (local ou pair)

: Connexion refusée ou chronométrée pendant longtemps; Le port est inaccessible.
Cause : le pare-feu natif ou homologue (Iptables, UFW, groupe de sécurité du fournisseur de cloud) bloque le port ou les blocs NAT / ACL intermédiaires.
Dépannage et résolution :

  • Utilisez Telnet Host Port / NC -vz Host Port / Curl - Connect-Timeout pour tester la connectivité du port sur ce serveur.

  • Vérifiez le groupe de sécurité Cloud Platform, Host Iptables et hôte des journaux de pare-feu.

  • Ouvrez ou ajoutez des règles d'autoriser (ouvrir uniquement les ports IP / les ports nécessaires ou ajuster les politiques de groupe de sécurité.

  • S'il est limité par l'ISP / Room Computer, contactez l'administrateur réseau ou modifiez la sortie.


Trois: délai d'expiration (blocage de temps de blocage / non bloquant et de délai d'attente)

Phénomène : le socket_connect échoue après une longue période, ou le script est bloqué.
Cause : le comportement de blocage par défaut n'est pas défini et le délai d'expiration raisonnable n'est pas défini; L'extrémité distante ne répond pas ou la réponse est lente.
Dépannage et résolution :

  • Utilisez une connexion non bloquante et implémentez le délai d'expiration vous-même, ou utilisez Stream_Socket_Client et spécifiez le paramètre Timeout.
    Exemple PHP Sockets (Set Timeout):

     <span><span><span class="hljs-variable">$sock</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_nonblock</span></span><span>(</span><span><span class="hljs-variable">$sock</span></span><span>);
    @</span><span><span class="hljs-title function_ invoke__">socket_connect</span></span><span>(</span><span><span class="hljs-variable">$sock</span></span><span>, </span><span><span class="hljs-variable">$host</span></span><span>, </span><span><span class="hljs-variable">$port</span></span><span>);
    </span><span><span class="hljs-variable">$start</span></span><span> = </span><span><span class="hljs-title function_ invoke__">time</span></span><span>();
    </span><span><span class="hljs-variable">$timeout</span></span><span> = </span><span><span class="hljs-number">5</span></span><span>;
    </span><span><span class="hljs-keyword">while</span></span><span> (!@</span><span><span class="hljs-title function_ invoke__">socket_connect</span></span><span>(</span><span><span class="hljs-variable">$sock</span></span><span>, </span><span><span class="hljs-variable">$host</span></span><span>, </span><span><span class="hljs-variable">$port</span></span><span>)) {
        </span><span><span class="hljs-variable">$err</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_last_error</span></span><span>(</span><span><span class="hljs-variable">$sock</span></span><span>);
        </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$err</span></span><span> === SOCKET_EISCONN) </span><span><span class="hljs-keyword">break</span></span><span>;
        </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">time</span></span><span>() - </span><span><span class="hljs-variable">$start</span></span><span> &gt; </span><span><span class="hljs-variable">$timeout</span></span><span>) {
            </span><span><span class="hljs-title function_ invoke__">socket_close</span></span><span>(</span><span><span class="hljs-variable">$sock</span></span><span>);
            </span><span><span class="hljs-keyword">throw</span></span><span> </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">Exception</span></span><span>(</span><span><span class="hljs-string">"connect timeout"</span></span><span>);
        }
        </span><span><span class="hljs-title function_ invoke__">usleep</span></span><span>(</span><span><span class="hljs-number">100000</span></span><span>);
    }
    </span><span><span class="hljs-title function_ invoke__">socket_set_block</span></span><span>(</span><span><span class="hljs-variable">$sock</span></span><span>);
    </span></span>
  • Simpler: Stream_Socket_Client ("tcp: // hôte: port", $ errno, $ errstr, $ timeout) .


Quatre: Autorisations et restrictions Selinux / Apparmor

Phénomène : le script ne peut pas établir de connexions externes, et il n'y a pas d'erreurs de réseau évidentes dans le journal.
Cause : Selinux ou Apparmor a des restrictions sur l'accès au réseau de processus; ou les restrictions Open_Basedir / Disable_Functions de PHP-FPM.
Dépannage et résolution :

  • Vérifiez /var/log/audit/audit.log (selinux) ou le journal système pour vérifier s'il y a des entrées rejetées.

  • Testez temporairement en mode permissif ou ajoutez des politiques SELINUX appropriées au service.

  • Confirmez que la configuration PHP ne désactive pas les fonctions liées au réseau (telles que Socket_Create est désactivée).


V: Protocole / L'inscription du port est mélangé avec TCP / UDP

Phénomène : La connexion est réussie mais aucune réponse ou les données sont anormales.
Raison : le service cible utilise UDP, mais le client utilise TCP, ou vice versa; Niveau de protocole (comme l'attente de TLS mais directement TCP).
Dépannage et résolution :

  • Confirmez que l'accord de service (HTTP / HTTPS, TLS, SMTP, Redis, MySQL, etc.) est cohérent avec la méthode de connexion.

  • S'il s'agit de TLS / SSL, vous devez utiliser Stream_Socket_Client ('ssl: // hôte: port', ...) ou utiliser la fonction d'extension OpenSSL Stream_Socket_enable_Crypto () sur les sockets.


Six: IPv6 / IPv4 Address Family Problèmes

Phénomène : l'hôte a à la fois IPv4 et IPv6, et la connexion à la mauvaise adresse qui provoque l'échec ou le délai d'attente.
résoudre :

  • Utilisez AF_INET (IPv4) ou AF_INET6 (IPv6) explicitement.

  • Utilisez getAddrinfo ou dns_get_record () pour obtenir l'adresse spécifique, puis sélectionnez la famille appropriée.


La poignée de main SSL / TLS a échoué (certificat, SNI, Cipher Suite)

Phénomène : la connexion est établie mais la poignée de main échoue et une erreur OpenSSL se produit.
Dépannage et résolution :

  • Utilisez Stream_Socket_Client ('ssl: // host: port', $ errno, $ errstr, $ timeout, stream_client_connect, $ context) et configurer le contexte SSL (Cafile, Verify_peer, sni). Exemple:

     <span><span><span class="hljs-variable">$context</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_context_create</span></span><span>([
        </span><span><span class="hljs-string">'ssl'</span></span><span> =&gt; [
            </span><span><span class="hljs-string">'verify_peer'</span></span><span> =&gt; </span><span><span class="hljs-literal">true</span></span><span>,
            </span><span><span class="hljs-string">'cafile'</span></span><span> =&gt; </span><span><span class="hljs-string">'/etc/ssl/certs/ca-certificates.crt'</span></span><span>,
            </span><span><span class="hljs-string">'SNI_enabled'</span></span><span> =&gt; </span><span><span class="hljs-literal">true</span></span><span>,
            </span><span><span class="hljs-string">'peer_name'</span></span><span> =&gt; </span><span><span class="hljs-string">'example.com'</span></span><span>,
        ]
    ]);
    </span><span><span class="hljs-variable">$fp</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_socket_client</span></span><span>(</span><span><span class="hljs-string">"ssl://example.com:443"</span></span><span>, </span><span><span class="hljs-variable">$errno</span></span><span>, </span><span><span class="hljs-variable">$errstr</span></span><span>, </span><span><span class="hljs-number">5</span></span><span>, STREAM_CLIENT_CONNECT, </span><span><span class="hljs-variable">$context</span></span><span>);
    </span></span>
  • Afficher la version OpenSSL et les suites de chiffre d'affaires soutenues par le serveur, et mettre à niveau ou ajuster la suite si nécessaire.

  • Vérifiez si la chaîne de certificat est terminée (manquant le certificat intermédiaire entraînera l'échec de la poignée de main).


8: limite de ressources (descripteur de fichier, limite supérieure de connexion simultanée)

Phénomène : La connexion a échoué sous une concurrence élevée et a rapporté "trop ​​de fichiers ouverts".
Cause : Système Ulimit -N ou Processus Limite maximale de fichiers ouverts.
Dépannage et résolution :

  • Utilisez Ulimit -N pour afficher la limite actuelle; Ajustez la configuration Systemd / Service ou /etc/security/limits.conf pour augmenter la limite.

  • Réutilisez les connexions (pools de connexions) dans le programme et utilisez un modèle asynchrone / axé sur les événements pour réduire le nombre de prises simultanées.


9: Gestion des erreurs inadéquates (manque de code / journal d'erreur spécifique)

Phénomène : ne connaissant que "la connexion a échoué", mais ne connaissant pas la raison.
résoudre :

  • Utilisez socket_last_error () et socket_strorror () pour obtenir des informations d'erreur détaillées:

     <span><span><span class="hljs-variable">$err</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_last_error</span></span><span>(</span><span><span class="hljs-variable">$sock</span></span><span>);
    </span><span><span class="hljs-variable">$msg</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_strerror</span></span><span>(</span><span><span class="hljs-variable">$err</span></span><span>);
    </span><span><span class="hljs-title function_ invoke__">error_log</span></span><span>(</span><span><span class="hljs-string">"socket error: <span class="hljs-subst">$err</span></span></span><span> - </span><span><span class="hljs-subst">$msg</span></span><span>");
    </span></span>
  • Capturez et enregistrez le contexte (IP cible, port, temps, temps de temps mort), combinant le journal système et l'analyse TCPDUmp.


Dix: proxy intermédiaire / proxy transparent / trafic modifié NAT

Phénomène : connexion au réseau externe mais le comportement est anormal (les demandes sont interceptées, remplacées, réécrites).
Dépannage et résolution :

  • Confirmez s'il existe des agents (Enterprise Network, ISP) ou WAF dans le chemin du réseau.

  • Utilisez TCPDUmp / Wireshark pour attraper des paquets pour voir si TCP TROS TROPE DE COUPE ET LES PACKETS SUIVANTS sont modifiés ou réinitialisés (RST).

  • S'il y a un proxy, ajoutez l'authentification ou accédez au canal proxy en fonction des exigences de proxy.


11: L'utilisation d'API de niveau supérieur est plus simple et plus fiable

Les prises natives sont puissantes mais plus complexes à écrire. Pour les scénarios TCP / HTTP / SSL courants, la priorité est donnée:

  • Stream_Socket_Client () : Timeout intégré, peut prendre directement en charge SSL: //, ce qui le rend plus facile à utiliser.

  • Extension Curl (libcurl): Convient pour HTTP / HTTPS, avec des options riches et des paramètres de délai d'attente.

  • Les bibliothèques de clients dédiées (Redis, MySQL, AMQP, etc.) traitent généralement de nombreux détails.

Exemple: utilisez Stream_Socket_Client pour connecter et lire et écrire avec concise:

 <span><span><span class="hljs-variable">$timeout</span></span><span> = </span><span><span class="hljs-number">5</span></span><span>;
</span><span><span class="hljs-variable">$fp</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_socket_client</span></span><span>(</span><span><span class="hljs-string">"tcp://example.com:12345"</span></span><span>, </span><span><span class="hljs-variable">$errno</span></span><span>, </span><span><span class="hljs-variable">$errstr</span></span><span>, </span><span><span class="hljs-variable">$timeout</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-variable">$fp</span></span><span>) {
    </span><span><span class="hljs-title function_ invoke__">error_log</span></span><span>(</span><span><span class="hljs-string">"connect failed: <span class="hljs-subst">$errno</span></span></span><span> </span><span><span class="hljs-subst">$errstr</span></span><span>");
} </span><span><span class="hljs-keyword">else</span></span><span> {
    </span><span><span class="hljs-title function_ invoke__">stream_set_timeout</span></span><span>(</span><span><span class="hljs-variable">$fp</span></span><span>, </span><span><span class="hljs-number">5</span></span><span>);
    </span><span><span class="hljs-title function_ invoke__">fwrite</span></span><span>(</span><span><span class="hljs-variable">$fp</span></span><span>, </span><span><span class="hljs-string">"hello\n"</span></span><span>);
    </span><span><span class="hljs-variable">$resp</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fgets</span></span><span>(</span><span><span class="hljs-variable">$fp</span></span><span>);
    </span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$fp</span></span><span>);
}
</span></span>

Conseils de débogage et de diagnostic (liste pratique)

  1. Ping / Dig / Telnet / NC local pour vérifier la connectivité de base.

  2. Imprimez et enregistrez Socket_Last_error et Socket_streror dans PHP.

  3. Utilisez la capture de paquets (TCPDUmp) pour confirmer si la poignée de main à trois voies est réussie et s'il existe des erreurs de première / ICMP.

  4. Vérifiez le journal du serveur (si accessible) pour voir si la demande de connexion ou le rejet est reçue.

  5. Vérifiez le pare-feu du serveur (iptables / nftables, Cloud Security Group), les politiques Selinux et les autorisations PHP-FPM.

  6. Essayez de vous connecter sur un autre hôte sur le même segment de machine ou de réseau pour résoudre les problèmes de sortie du réseau.

  7. S'il s'agit d'un problème TLS, Test OpenSSL S_Client -Connect Host: Port -ServerName Host pour obtenir les détails de la poignée de main.