Aktueller Standort: Startseite> Neueste Artikel> Was sind die häufigen Probleme, die auftreten, wenn Socket_Create mit Remote -Hosts verbunden ist? Wie löst ich es?

Was sind die häufigen Probleme, die auftreten, wenn Socket_Create mit Remote -Hosts verbunden ist? Wie löst ich es?

gitbox 2025-09-21

2. Blockierung von Firewall/Netzwerkrichtlinien (lokal oder Peer-Side)

: Verbindung lehnte oder zeitlich abgelehnt; Der Hafen ist nicht erreichbar.
Ursache : Die native oder Peer -Firewall (Iptables, UFW, Cloud -Anbieter -Sicherheitsgruppe) blockiert den Port oder die mittleren NAT/ACL -Blöcke.
Fehlerbehebung und Lösung :

  • Verwenden Sie Telnet Host -Port / NC -VZ -Host -Port / curl - -Connect -Timeout, um die Anschlusskonnecke auf diesem Server zu testen.

  • Überprüfen Sie die Cloud Platform Security Group, Host Iptables und Host Firewall -Protokolle.

  • Offen oder hinzufügen zulassen Regeln (nur die erforderlichen IP/Ports öffnen) oder die Sicherheitsgruppenrichtlinien anpassen.

  • Wenn es durch den ISP/Computer -Raum eingeschränkt wird, wenden Sie sich an den Netzwerkadministrator oder ändern Sie den Ausgang.


Drei: Zeitüberschreitungen (Blockierung/Nicht-Blockier- und Zeitleitungszeiteinstellung)

Phänomen : Der Socket_Connect schlägt nach langer Zeit fehl, oder das Skript ist blockiert.
Ursache : Das Standard -Blockierungsverhalten ist nicht festgelegt und das angemessene Zeitlimit ist nicht festgelegt. Das entfernte Ende reagiert nicht mehr oder die Reaktion ist langsam.
Fehlerbehebung und Lösung :

  • Verwenden Sie eine nicht blockierende Verbindung und implementieren Sie die Zeitlimit-Überprüfung oder verwenden Sie Stream_Socket_Client und geben Sie den Zeitüberschreitungsparameter an.
    PHP -Sockets Beispiel (Zeitlimit festlegen):

     <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>
  • Einfacher: stream_socket_client ("tcp: // host: port", $ errno, $ errstr, $ timeout) .


Vier: Berechtigungen und Selinux/Apparmor -Beschränkungen

Phänomen : Das Skript kann keine externen Verbindungen herstellen, und es gibt keine offensichtlichen Netzwerkfehler im Protokoll.
Ursache : Selinux oder Apparmor verfügt über Einschränkungen des Prozessnetzwerkzugriffs. oder die Einschränkungen von Open_Basedir / Disable_functions von PHP-FPM.
Fehlerbehebung und Lösung :

  • Check /var/log/audit/audit.log (selinux) oder ein Systemprotokoll, um zu überprüfen, ob abgelehnte Einträge vorhanden sind.

  • Testen Sie vorübergehend im zulässigen Modus oder fügen Sie dem Dienst geeignete Selinux -Richtlinien hinzu.

  • Bestätigen Sie, dass die PHP-Konfiguration keine netzwerkbezogenen Funktionen deaktiviert (z. B. Socket_Create ist deaktiviert).


V: Protokoll/Portmismatch wird mit TCP/UDP gemischt

Phänomen : Die Verbindung ist erfolgreich, aber keine Antwort oder die Daten sind abnormal.
Grund : Der Zieldienst verwendet UDP, der Client verwendet jedoch TCP oder umgekehrt. Protokollspiegel (z. B. erwartet TLS, aber direkt TCP).
Fehlerbehebung und Lösung :

  • Bestätigen Sie, dass die Servicevereinbarung (HTTP/HTTPS, TLS, SMTP, Redis, MySQL usw.) mit der Verbindungsmethode übereinstimmt.

  • Wenn es sich um TLS/SSL handelt, müssen Sie Stream_Socket_Client ('SSL: // Host: Port', ...) verwenden oder die OpenSSL -Erweiterungsfunktion stream_socket_enable_crypto () auf Sockets verwenden.


Sechs: IPv6/IPv4 -Adressfamilienprobleme

Phänomen : Der Host hat sowohl IPv4 als auch IPv6, und eine Verbindung zu der falschen Adressfamilie führt zu einem Ausfall oder einer Auszeit.
lösen :

  • Verwenden Sie explizit AF_Inet (IPv4) oder AF_Inet6 (IPv6).

  • Verwenden Sie GetAddrinfo oder dns_get_record (), um die spezifische Adresse zu erhalten, und wählen Sie dann die entsprechende Familie aus.


SSL/TLS -Handshake fehlgeschlagen (Zertifikat, SNI, Cipher Suite)

Phänomen : Die Verbindung wird hergestellt, aber der Handschlag fällt aus, und ein OpenSSL -Fehler tritt auf.
Fehlerbehebung und Lösung :

  • Verwenden Sie Stream_Socket_Client ('ssl: // host: port', $ errno, $ errstr, $ timeout, stream_client_connect, $ context) und konfigurieren Sie den SSL -Kontext (CAFILE, verify_peer, SNI). Beispiel:

     <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>
  • View OpenSSL-Version und servergestützte Cipher-Suiten und upgrade oder passen Sie die Suite bei Bedarf an.

  • Überprüfen Sie, ob die Zertifikatkette abgeschlossen ist (das Fehlen des Zwischenzertifikats lässt den Handschlag fehlschlagen).


8: Ressourcenbegrenzung (Dateideskriptor, gleichzeitige Verbindungs ​​Obergrenze)

Phänomen : Die Verbindung ist unter hoher Parallelität fehlgeschlagen und berichtete "zu viele offene Dateien".
Ursache : System Ulimit -n oder Maximum Open -Files -Grenze.
Fehlerbehebung und Lösung :

  • Verwenden Sie Ulimit -n, um die aktuelle Grenze anzuzeigen. Passen Sie die Systemd/Service -Konfiguration oder /etc/security/limits.conf an, um die Grenze zu erhöhen.

  • Wiederverwenden Verbindungen (Verbindungspools) im Programm und verwenden Sie ein asynchrones/ereignisorientiertes Modell, um die Anzahl der gleichzeitigen Steckdosen zu verringern.


9: Unzureichende Fehlerbehandlung (Mangel an spezifischem Fehlercode/Protokoll)

Phänomen : Nur zu wissen, dass "Verbindung fehlgeschlagen" ist, aber den Grund nicht kannte.
lösen :

  • Verwenden Sie Socket_Last_error () und socket_strerror (), um detaillierte Fehlerinformationen zu erhalten:

     <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>
  • Erfassen und zeichnen Sie den Kontext (Ziel -IP, Port, Zeit, Zeitüberschreitungszeit) auf und kombinieren Sie das Systemprotokoll und die TCPDump -Analyse.


Zehn: Intermediate Proxy/Transparent Proxy/NAT Modifizierte Datenverkehr

Phänomen : Verbinden mit dem externen Netzwerk, aber das Verhalten ist abnormal (Anfragen werden abgefangen, ersetzt, umgeschrieben).
Fehlerbehebung und Lösung :

  • Bestätigen Sie, ob es Agenten (Enterprise Network, ISP) oder WAF im Netzwerkpfad gibt.

  • Verwenden Sie TCPDUMP / Wireshark, um Pakete zu fangen, um festzustellen, ob TCP dreimal Handshake und nachfolgende Pakete modifiziert oder zurückgesetzt werden (RST).

  • Wenn es einen Proxy gibt, fügen Sie die Authentifizierung hinzu oder gehen Sie gemäß den Proxy -Anforderungen zum Proxy -Kanal.


11: Die Verwendung von APIs auf höherer Ebene ist einfacher und zuverlässiger

Einheimische Sockel sind mächtig, aber komplexer zu schreiben. Für gemeinsame TCP/HTTP/SSL -Szenarien wird die Priorität angegeben:

  • stream_socket_client () : integrierte Zeitüberschreitung kann SSL: // direkt unterstützen und die Verwendung erleichtern.

  • CURL (libcurl) Erweiterung: Geeignet für HTTP/HTTPS mit umfangreichen Optionen und Zeitüberschreitungseinstellungen.

  • Dedizierte Client -Bibliotheken (Redis, MySQL, AMQP usw.) befassen sich normalerweise mit vielen Details.

Beispiel: Verwenden Sie Stream_Socket_Client , um sich präzise zu verbinden und zu lesen und zu schreiben:

 <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>

Debugging- und Diagnose -Tipps (praktische Liste)

  1. Lokale Ping / Dig / Telnet / NC zuerst, um die grundlegende Konnektivität zu überprüfen.

  2. Drucken und zeichnen Sie Socket_Last_error und Socket_Strerror in PHP auf.

  3. Verwenden Sie Paket Capture (TCPDump), um zu bestätigen, ob der Drei-Wege-Handshake erfolgreich ist und ob RST/ICMP-Fehler vorliegen.

  4. Überprüfen Sie das Serverprotokoll (falls zugänglich), um festzustellen, ob die Verbindungsanforderung oder -ablassung empfangen wird.

  5. Überprüfen Sie die Server-Firewall (Iptables/Nftables, Cloud Security Group), Selinux-Richtlinien und PHP-FPM-Berechtigungen.

  6. Versuchen Sie, eine Verbindung über einen anderen Host auf demselben Computer- oder Netzwerksegment herzustellen, um die Probleme mit dem Netzwerk -Exit -Problem zu beheben.

  7. Wenn es sich um ein TLS -Problem handelt, testen Sie OpenSSL S_CLIENT -Connect Host: Port -Servername -Host, um die Handshake -Details zu erhalten.