PHP로 소켓을 프로그래밍 할 때 Socket_accept () 는 청취 소켓에 연결된 클라이언트 연결을 수락하는 핵심 기능입니다. 그러나 실제 개발 중에 Socket_accept ()가 연결을받을 수없는 상황을 만날 수 있습니다. 이러한 유형의 문제는 종종 혼란 스럽습니다. 이 기사는 오류의 5 가지 일반적인 원인을 나열하고 문제를 신속하게 찾아서 해결하는 데 도움이되는 해당 솔루션을 제공합니다.
문제 설명 :
소켓을 생성하고 주소를 바인딩하면 Socket_Listen () 이 호출되지 않으면 소켓이 연결 요청을 듣지 않으며 Socket_accept ()는 성공하지 못합니다.
해결책:
Socket_Accept ()를 호출하기 전에 Socket_Listen () 에게 전화하십시오.
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 12345);
socket_listen($socket); // 필수적인
$client = socket_accept($socket);
문제 설명 :
바인딩 된 포트가 다른 프로그램에 의해 점유 된 경우, socket_bind ()는 실패하므로 Socket_accept ()를 포함한 모든 후속 작업에서 오류가 발생합니다.
해결책:
포트가 점유되어 있는지 확인하려면 NetStat -tlnp | 와 같은 명령을 사용할 수 있습니다. Grep 12345 . 또한 socket_bind () 의 반환 값을 확인하고 socket_last_error ()를 사용하여 오류 메시지를 얻습니다.
if (!socket_bind($socket, '0.0.0.0', 12345)) {
echo "바인딩이 실패했습니다: " . socket_strerror(socket_last_error($socket));
exit;
}
문제 설명 :
서버가 연결을 기다리는 경우 클라이언트는 전혀 연결하려고하거나 잘못된 주소와 포트에 연결하지 않으므로 당연히 Socket_accept () 를 트리거 할 수 없습니다.
해결책:
클라이언트의 연결 주소와 포트가 올바른지 확인하십시오.
$client = stream_socket_client("tcp://m66.net:12345", $errno, $errstr, 30);
Telnet M66.net 12345를 사용하여 연결이 성공할 수 있는지 수동으로 테스트 할 수도 있습니다.
문제 설명 :
socket_accept ()는 클라이언트 연결이 없으면 기다릴 차단 함수입니다. 이것은 프로그램이 붙어있는 것처럼 보이게 할 수 있습니다.
해결책:
socket_set_nonblock ()을 사용하여 청취 소켓을 비 블로킹 모드로 설정하거나 socket_select ()를 사용하여 시간 초과 대기를 구현할 수 있습니다.
socket_set_nonblock($socket);
$client = @socket_accept($socket);
if ($client === false) {
echo "현재 연결 요청이 없습니다\n";
}
또는:
$read = [$socket];
$write = $except = [];
if (socket_select($read, $write, $except, 5) > 0) {
$client = socket_accept($socket);
}
문제 설명 :
서버 청취 포트가 올바르게 설정되어 있지만 운영 체제의 방화벽 규칙 또는 클라우드 서버의 보안 그룹 정책은 클라이언트 연결 요청을 방지합니다.
해결책:
서버의 포트를 확인하고 엽니 다. 예를 들어, Linux에서 iptables 또는 Firewalld를 사용하면 Port 12345에 액세스하거나 AWS 및 Alibaba Cloud와 같은 클라우드 서비스 플랫폼에서 해당 포트를 열 수 있습니다.