막힘을 피하기 위해 연결 프로세스를 제어하기 위해 다음 방법을 사용할 수 있습니다.
PHP의 소켓은 차단 모드로 기본값을 얻습니다. 즉, 연결이 성공하거나 시간이 초과 될 때까지 연결을 기다리는 동안 프로그램이 중단됩니다. 비 블로킹 모드를 설정 하여이 차단 동작을 피할 수 있습니다.
socket_set_block($socket); // 차단 모드로 설정합니다
socket_set_nonblock($socket); // 비 블로킹 모드로 설정합니다
비 블로킹 모드에서 연결 요청은 원격 호스트의 응답을 기다리지 않고 즉시 반환됩니다. 따라서 프로그램은 다른 작업을 계속 수행 할 수 있습니다. 연결이 성공하거나 실패 할 때까지 socket_select를 통해 연결 상태를 모니터링 할 수 있습니다.
$timeout = 5; // 시간 초과 설정
$start_time = time();
while (true) {
if (time() - $start_time > $timeout) {
echo "연결 시간 초과\n";
break;
}
$result = socket_addrinfo_connect($socket, $address, $port);
if ($result) {
echo "연결이 성공적으로 연결됩니다\n";
break;
}
// 기다린 후 다시 시도하십시오
usleep(100000);
}
여러 소켓 연결을 동시에 처리 해야하는 경우 Socket_Select를 사용하여 여러 소켓의 상태를 모니터링 할 수 있습니다. 이를 통해 루프에서 여러 연결을 감지하여 각 연결의 차단 문제를 피할 수 있습니다.
$read = array($socket);
$write = null;
$except = null;
$timeout = 5; // 시간 초과 설정
// 사용 socket_select 시간 초과 및 차단 감지
$changed_sockets = socket_select($read, $write, $except, $timeout);
if ($changed_sockets === false) {
echo "socket_select 오류가 발생했습니다\n";
} elseif ($changed_sockets > 0) {
// 如果연결이 성공적으로 연결됩니다,프로세스 연결
echo "연결이 성공적으로 연결됩니다\n";
} else {
echo "연결 시간 초과\n";
}
socket_select를 사용하면 비 차단 모드에서 연결이 성공했는지 확인할 수 있으므로 기존 차단 연결 프로세스를 피할 수 있습니다.
socket_addrinfo_connect를 직접 사용하는 것 외에도 PHP는 소켓 연결을 생성하고 관리하기 위해 stream_socket_client 함수를 제공합니다. Stream_Socket_Client는 보다 고급 기능을 지원하며 시간 초과 및 비 블로킹 모드를 쉽게 설정할 수 있습니다.
$address = 'tcp://m66.net:80';
$timeout = 5; // 시간 초과 설정
$context = stream_context_create(['socket' => ['timeout' => $timeout]]);
$socket = stream_socket_client($address, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context);
if ($socket === false) {
echo "연결이 실패했습니다: $errstr ($errno)\n";
} else {
echo "연결이 성공적으로 연결됩니다\n";
fclose($socket);
}
Stream_Socket_Client는 비 블로킹 연결을 지원할뿐만 아니라 장기 차단을 피하기 위해 시간 초과 매개 변수를 통해 연결 시간 초과를 쉽게 설정할 수 있습니다.
socket_addrinfo_connect 또는 stream_socket_client를 사용하든 적절한 연결 시간 초과를 설정하는 것이 매우 중요합니다. 원격 호스트가 오랫동안 응답하지 않으면 프로그램은 오랫동안 기다릴 것입니다. 이를 방지하기 위해 합리적인 시간 초과 메커니즘을 설정하는 것이 매우 중요합니다.
socket_addrinfo_connect를 사용하는 경우 연결 진행 상황을 모니터링하고 타임 아웃을 설정하여 긴 차단을 피할 수 있습니다.
$timeout = 5; // 타임 아웃은입니다5두번째
$start_time = time();
while (time() - $start_time < $timeout) {
$result = socket_addrinfo_connect($socket, $address, $port);
if ($result) {
echo "연결이 성공적으로 연결됩니다\n";
break;
}
usleep(100000); // 다시 시도하기 전에 잠시 기다리십시오
}
연결 시간이 사전 설정 타임 아웃 시간을 초과하면 프로그램은 무한 대기 상태로 떨어지지 않도록 연결을 적극적으로 방해 할 수 있습니다.