: 연결은 오랫동안 거부되거나 시간을 초과했습니다. 포트는 도달 할 수 없습니다.
원인 : 기본 또는 피어 방화벽 (IPTABLE, UFW, 클라우드 공급 업체 보안 그룹)은 포트 또는 중간 NAT/ACL 블록을 차단합니다.
문제 해결 및 해결 :
Telnet Host Port / NC -VZ 호스트 포트 / CURL -CONNECT -TIMEOUT을 사용 하여이 서버에서 포트 연결을 테스트하십시오.
클라우드 플랫폼 보안 그룹, 호스트 iptables 및 호스트 방화벽 로그를 확인하십시오.
허용 규칙 (필요한 IP/포트 만 열거)을 열거 나 추가하거나 보안 그룹 정책을 조정하십시오.
ISP/Computer Room에서 제한되는 경우 네트워크 관리자에게 문의하거나 출구를 변경하십시오.
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> > </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) .
현상 : 스크립트는 외부 연결을 설정할 수 없으며 로그에는 명백한 네트워크 오류가 없습니다.
원인 : Selinux 또는 Apparmor는 프로세스 네트워크 액세스에 제한이 있습니다. 또는 php-fpm의 Open_baseDir / disable_functions 제한 제한.
문제 해결 및 해결 :
거부 된 항목이 있는지 확인하려면 /var/log/audit/audit.log (selinux) 또는 시스템 로그를 확인하십시오.
허용 모드로 일시적으로 테스트하거나 서비스에 적절한 SELINUX 정책을 추가하십시오.
PHP 구성이 네트워크 관련 기능을 비활성화하지 않음을 확인하십시오 (예 : Socket_create 가 비활성화됨).
현상 : 연결은 성공적이지만 응답이나 데이터는 비정상적입니다.
이유 : 대상 서비스는 UDP를 사용하지만 클라이언트는 TCP를 사용하거나 그 반대도 마찬가지입니다. 프로토콜 레벨 (예 : TLS를 기대하지만 직접 TCP).
문제 해결 및 해결 :
서비스 계약 (http/https, tls, smtp, redis, mysql 등)이 연결 방법과 일치하는지 확인하십시오.
tls/ssl 인 경우 stirm_socket_client ( 'ssl : // host : port', ...)를 사용하거나 소켓에서 OpenSSL Extension 함수 stream_socket_enable_crypto ()를 사용해야합니다.
현상 : 호스트는 IPv4와 IPv6을 모두 가지고 있으며 잘못된 주소에 연결하면 실패 또는 시간 초과가 발생합니다.
해결하다 :
AF_INET (IPV4) 또는 AF_INET6 (IPv6)을 명시 적으로 사용하십시오.
getAddrinfo 또는 dns_get_record ()를 사용하여 특정 주소를 얻은 다음 적절한 패밀리를 선택하십시오.
현상 : 연결이 설정되었지만 핸드 셰이크가 실패하고 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> => [
</span><span><span class="hljs-string">'verify_peer'</span></span><span> => </span><span><span class="hljs-literal">true</span></span><span>,
</span><span><span class="hljs-string">'cafile'</span></span><span> => </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> => </span><span><span class="hljs-literal">true</span></span><span>,
</span><span><span class="hljs-string">'peer_name'</span></span><span> => </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 버전 및 서버 지원 암호 스위트를보고 필요한 경우 스위트를 업그레이드하거나 조정하십시오.
인증 체인이 완료되었는지 확인하십시오 (중간 증명서가 없으면 악수가 실패합니다).
현상 : 연결이 높은 동시성에서 실패했으며 "너무 많은 파일"을보고했습니다.
원인 : 시스템 ULIMIT -N 또는 프로세스 최대 개방형 파일 제한.
문제 해결 및 해결 :
Ulimit -N을 사용하여 현재 한도를보십시오. 한계를 높이려면 SystemD/Service 구성 또는 /etc/security/limits.conf 를 조정하십시오.
프로그램의 연결 (연결 풀)을 재사용하고 동시 소켓 수를 줄이기 위해 비동기/이벤트 중심 모델을 사용하십시오.
현상 : "연결 실패"만 아는 것만 알고 있었지만 그 이유는 모릅니다.
해결하다 :
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 분석을 결합하십시오.
현상 : 외부 네트워크에 연결하지만 동작은 비정상적입니다 (요청은 가로 채기, 교체, 재 작성).
문제 해결 및 해결 :
네트워크 경로에 에이전트 (Enterprise Network, ISP) 또는 WAF가 있는지 확인하십시오.
TCPDUMP / WIRSHARK를 사용하여 패킷을 잡아 TCP 3 회 핸드 셰이크와 후속 패킷이 수정되었거나 재설정되었는지 확인하십시오 (RST).
프록시가있는 경우 프록시 요구 사항에 따라 인증을 추가하거나 프록시 채널로 이동하십시오.
기본 소켓은 강력하지만 글을 쓰는 것이 더 복잡합니다. 일반적인 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>로컬 Ping / Dig / Telnet / NC 먼저 기본 연결을 확인합니다.
php의 socket_last_error 및 socket_strerror 인쇄 및 레코드.
패킷 캡처 (TCPDUMP)를 사용하여 3 방향 핸드 셰이크가 성공했는지 여부와 RST/ICMP 오류가 있는지 확인하십시오.
연결 요청 또는 거부가 수신되었는지 확인하려면 서버 로그 (액세스 가능한 경우)를 확인하십시오.
서버 방화벽 (IPTABLE/NFTABLE, 클라우드 보안 그룹), SELINUX 정책 및 PHP-FPM 권한을 확인하십시오.
네트워크 종료 문제를 해결하기 위해 동일한 머신 또는 네트워크 세그먼트의 다른 호스트에 연결하십시오.
TLS 문제인 경우 Testslssl S_CLIENT -CONNECT 호스트 : PORT -SERVERNAME 호스트를 통해 핸드 셰이크 세부 정보를 얻으십시오.