현재 위치: > 최신 기사 목록> Socket_create가 원격 호스트에 연결될 때 발생하는 일반적인 문제는 무엇입니까? 그것을 해결하는 방법?

Socket_create가 원격 호스트에 연결될 때 발생하는 일반적인 문제는 무엇입니까? 그것을 해결하는 방법?

gitbox 2025-09-21

2. 방화벽/네트워크 정책 차단 (로컬 또는 피어 사이드)

: 연결은 오랫동안 거부되거나 시간을 초과했습니다. 포트는 도달 할 수 없습니다.
원인 : 기본 또는 피어 방화벽 (IPTABLE, UFW, 클라우드 공급 업체 보안 그룹)은 포트 또는 중간 NAT/ACL 블록을 차단합니다.
문제 해결 및 해결 :

  • Telnet Host Port / NC -VZ 호스트 포트 / CURL -CONNECT -TIMEOUT을 사용 하여이 서버에서 포트 연결을 테스트하십시오.

  • 클라우드 플랫폼 보안 그룹, 호스트 iptables 및 호스트 방화벽 로그를 확인하십시오.

  • 허용 규칙 (필요한 IP/포트 만 열거)을 열거 나 추가하거나 보안 그룹 정책을 조정하십시오.

  • ISP/Computer Room에서 제한되는 경우 네트워크 관리자에게 문의하거나 출구를 변경하십시오.


3 : 시간 초과 (차단/비 차단 및 시간 초과 시간 설정)

PHENOMENON : 오랜 시간이 지나면 Socket_Connect가 실패하거나 스크립트가 차단됩니다.
원인 : 기본 차단 동작이 설정되지 않았으며 합리적인 시간 초과가 설정되지 않았습니다. 원격 끝은 응답하지 않거나 응답이 느립니다.
문제 해결 및 해결 :

  • 비 차단 연결을 사용하고 시간 초과를 구현하거나 직접 확인하거나 Stream_Socket_Client를 사용하고 타임 아웃 매개 변수를 지정하십시오.
    PHP 소켓 예제 (시간 초과 설정) :

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


4 : 권한 및 Selinux/Apparmor 제한

현상 : 스크립트는 외부 연결을 설정할 수 없으며 로그에는 명백한 네트워크 오류가 없습니다.
원인 : Selinux 또는 Apparmor는 프로세스 네트워크 액세스에 제한이 있습니다. 또는 php-fpm의 Open_baseDir / disable_functions 제한 제한.
문제 해결 및 해결 :

  • 거부 된 항목이 있는지 확인하려면 /var/log/audit/audit.log (selinux) 또는 시스템 로그를 확인하십시오.

  • 허용 모드로 일시적으로 테스트하거나 서비스에 적절한 SELINUX 정책을 추가하십시오.

  • PHP 구성이 네트워크 관련 기능을 비활성화하지 않음을 확인하십시오 (예 : Socket_create 가 비활성화됨).


V : 프로토콜/포트 불일치는 TCP/UDP와 혼합됩니다

현상 : 연결은 성공적이지만 응답이나 데이터는 비정상적입니다.
이유 : 대상 서비스는 UDP를 사용하지만 클라이언트는 TCP를 사용하거나 그 반대도 마찬가지입니다. 프로토콜 레벨 (예 : TLS를 기대하지만 직접 TCP).
문제 해결 및 해결 :

  • 서비스 계약 (http/https, tls, smtp, redis, mysql 등)이 연결 방법과 일치하는지 확인하십시오.

  • tls/ssl 인 경우 stirm_socket_client ( 'ssl : // host : port', ...)를 사용하거나 소켓에서 OpenSSL Extension 함수 stream_socket_enable_crypto ()를 사용해야합니다.


6 : IPv6/IPv4 주소 제품군 문제

현상 : 호스트는 IPv4와 IPv6을 모두 가지고 있으며 잘못된 주소에 연결하면 실패 또는 시간 초과가 발생합니다.
해결하다 :

  • AF_INET (IPV4) 또는 AF_INET6 (IPv6)을 명시 적으로 사용하십시오.

  • getAddrinfo 또는 dns_get_record ()를 사용하여 특정 주소를 얻은 다음 적절한 패밀리를 선택하십시오.


SSL/TLS 핸드 셰이크 실패 (인증서, SNI, 암호 스위트)

현상 : 연결이 설정되었지만 핸드 셰이크가 실패하고 OpenSSL 오류가 발생합니다.
문제 해결 및 해결 :

  • stream_socket_client ( 'ssl : // host : port', $ errno, $ errstr, $ timeout, stream_client_connect, $ context)를 사용하고 SSL 컨텍스트 (cafile, verify_peer, sni)를 구성하십시오. 예:

     <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>
  • OpenSSL 버전 및 서버 지원 암호 스위트를보고 필요한 경우 스위트를 업그레이드하거나 조정하십시오.

  • 인증 체인이 완료되었는지 확인하십시오 (중간 증명서가 없으면 악수가 실패합니다).


8 : 리소스 한계 (파일 디스크립터, 동시 연결 상한)

현상 : 연결이 높은 동시성에서 실패했으며 "너무 많은 파일"을보고했습니다.
원인 : 시스템 ULIMIT -N 또는 프로세스 최대 개방형 파일 제한.
문제 해결 및 해결 :

  • Ulimit -N을 사용하여 현재 한도를보십시오. 한계를 높이려면 SystemD/Service 구성 또는 /etc/security/limits.conf 를 조정하십시오.

  • 프로그램의 연결 (연결 풀)을 재사용하고 동시 소켓 수를 줄이기 위해 비동기/이벤트 중심 모델을 사용하십시오.


9 : 부적절한 오류 처리 (특정 오류 코드/로그 부족)

현상 : "연결 실패"만 아는 것만 알고 있었지만 그 이유는 모릅니다.
해결하다 :

  • Socket_last_error ()Socket_strerror ()를 사용하여 자세한 오류 정보를 얻으십시오.

     <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>
  • 컨텍스트 (대상 IP, 포트, 시간, 시간 초과 시간)를 캡처하고 기록하여 시스템 로그와 TCPDUMM 분석을 결합하십시오.


10 : 중간 프록시/투명 프록시/NAT 수정 트래픽

현상 : 외부 네트워크에 연결하지만 동작은 비정상적입니다 (요청은 가로 채기, 교체, 재 작성).
문제 해결 및 해결 :

  • 네트워크 경로에 에이전트 (Enterprise Network, ISP) 또는 WAF가 있는지 확인하십시오.

  • TCPDUMP / WIRSHARK를 사용하여 패킷을 잡아 TCP 3 회 핸드 셰이크와 후속 패킷이 수정되었거나 재설정되었는지 확인하십시오 (RST).

  • 프록시가있는 경우 프록시 요구 사항에 따라 인증을 추가하거나 프록시 채널로 이동하십시오.


11 : 더 높은 수준의 API를 사용하는 것이 더 간단하고 신뢰할 수 있습니다

기본 소켓은 강력하지만 글을 쓰는 것이 더 복잡합니다. 일반적인 TCP/HTTP/SSL 시나리오의 경우 우선 순위가 부여됩니다.

  • stream_socket_client () : 내장 타임 아웃은 ssl : //을 직접 지원하여 사용하기 쉽도록 할 수 있습니다.

  • CURL (LIBCURL) 확장 : 풍부한 옵션 및 시간 초과 설정이있는 HTTP/HTTPS에 적합합니다.

  • 전용 클라이언트 라이브러리 (Redis, MySQL, AMQP 등)는 일반적으로 많은 세부 사항을 처리합니다.

예 : stream_socket_client를 사용하여 간결하게 연결하고 읽고 쓰십시오.

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

디버깅 및 진단 팁 (실용 목록)

  1. 로컬 Ping / Dig / Telnet / NC 먼저 기본 연결을 확인합니다.

  2. php의 socket_last_errorsocket_strerror 인쇄 및 레코드.

  3. 패킷 캡처 (TCPDUMP)를 사용하여 3 방향 핸드 셰이크가 성공했는지 여부와 RST/ICMP 오류가 있는지 확인하십시오.

  4. 연결 요청 또는 거부가 수신되었는지 확인하려면 서버 로그 (액세스 가능한 경우)를 확인하십시오.

  5. 서버 방화벽 (IPTABLE/NFTABLE, 클라우드 보안 그룹), SELINUX 정책 및 PHP-FPM 권한을 확인하십시오.

  6. 네트워크 종료 문제를 해결하기 위해 동일한 머신 또는 네트워크 세그먼트의 다른 호스트에 연결하십시오.

  7. TLS 문제인 경우 Testslssl S_CLIENT -CONNECT 호스트 : PORT -SERVERNAME 호스트를 통해 핸드 셰이크 세부 정보를 얻으십시오.