PHP에서 기본 소켓으로 프로그래밍 할 때 Socket_accept () 함수는 클라이언트 연결 요청을 수락하는 데 사용되지만 기본적 으로이 기능은 차단됩니다. 즉, 클라이언트 연결이 없으면 프로그램이 대기 및 자동으로 시간을 초과 할 수 없습니다. 연결 대기로 인해 프로그램이 고정되거나 응답하지 않도록하기 위해 Socket_set_Timeout ()를 결합하여 연결 시간 초과 제어를 달성하여 프로그램의 견고성을 향상시킬 수 있습니다.
이 기사는 Socket_accept () 및 Socket_set_timeout ()을 사용하여 PHP 연결 시간 초과 컨트롤의 기능을 구현하는 방법을 자세히 소개합니다.
socket_accept ($ socket)
클라이언트 연결 요청 차단을 기다리는 대기, 연결 요청이 있으면 새 소켓 리소스가 반환됩니다. 그렇지 않으면 차단됩니다.
socket_set_timeout ($ 소켓, $ 초, $ 마이크로 초)
지정된 소켓의 시간 초과 시간을 설정합니다. 시간 초과 후 읽기/쓰기 작업은 시간 초과 오류를 반환합니다.
socket_set_timeout ()는 읽기 및 쓰기 작업을위한 타임 아웃 컨트롤이며 Socket_accept () 의 차단 대기 시간을 직접 제어 할 수 없습니다. 따라서 실제 연결 대기 시간 초과를 달성하기 위해 다른 방법 (예 : 비 블로킹 모드 또는 Socket_Select () 사용)와 협력해야합니다.
청취 소켓을 비 블로킹 모드 <br>로 설정하십시오 이러한 방식으로 socket_accept ()를 호출하는 것은 차단되지 않습니다. 연결 요청이 없으면 즉시 거짓이 반환됩니다.
루프 + 지연을 사용하여 시간 초과를 판단하십시오 . <br> 루프에서 socket_accept ()를 반복적으로 호출하십시오. False가 반환되면 타임 아웃이 시간 초과되었는지 여부를 결정하십시오. 타임 아웃이 시간을 초과하면 대기가 종료됩니다.
연결이 수신되면 socket_set_timeout ()을 사용하여 읽기 및 쓰기 시간 초과 <br> 후속 데이터 전송 중에 시간 초과 제어가 있는지 확인하십시오.
<?php
$host = "0.0.0.0";
$port = 12345;
$timeoutSeconds = 10; // 최대 대기 연결 시간
// 만들다 TCP socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
die("socket_create failed: " . socket_strerror(socket_last_error()) . "\n");
}
// 바인드 포트
if (socket_bind($socket, $host, $port) === false) {
die("socket_bind failed: " . socket_strerror(socket_last_error($socket)) . "\n");
}
// 포트를 들어보세요
if (socket_listen($socket, 5) === false) {
die("socket_listen failed: " . socket_strerror(socket_last_error($socket)) . "\n");
}
// 모니터링을 설정하십시오 socket 차단되지 않습니다
socket_set_nonblock($socket);
$startTime = time();
$clientSocket = false;
echo "클라이언트 연결을 기다리고 있습니다,시간 초과:{$timeoutSeconds}두번째\n";
while (true) {
$clientSocket = @socket_accept($socket);
if ($clientSocket !== false) {
echo "클라이언트가 연결되어 있습니다!\n";
break;
}
// 타임 아웃이 있는지 확인하십시오
if ((time() - $startTime) >= $timeoutSeconds) {
echo "클라이언트 연결을 기다리고 있습니다超时。\n";
break;
}
// 잠 100ms 피하다 CPU 너무 높은 점유
usleep(100000);
}
if ($clientSocket !== false) {
// 클라이언트 설정 socket 읽기 및 쓰기 시간 초과,예를 들어 5 두번째
socket_set_option($clientSocket, SOL_SOCKET, SO_RCVTIMEO, ["sec"=>5, "usec"=>0]);
socket_set_option($clientSocket, SOL_SOCKET, SO_SNDTIMEO, ["sec"=>5, "usec"=>0]);
// 클라이언트 데이터를 읽는 예
$buf = '';
$bytes = socket_recv($clientSocket, $buf, 2048, 0);
if ($bytes === false) {
echo "데이터를받지 못하거나 시간을 초과하지 않았습니다:" . socket_strerror(socket_last_error($clientSocket)) . "\n";
} else {
echo "클라이언트 데이터를 받았습니다:" . $buf . "\n";
}
socket_close($clientSocket);
}
socket_close($socket);
?>
비 블로킹 청취 : socket_set_nonblock ()을 사용하여 socket_accept () 차단을 피하여 타임 아웃 로직을 사용자 정의 할 수 있습니다.
연결을 기다리기 위해 루핑 : Socket_Accept ()가 호출 될 때마다 연결이 없으면 즉시 False를 반환하고 시간 초과 조건에 도달하는지 여부를 결정합니다. 시간 초과가 만료되지 않으면 계속 기다리십시오.
연결 후 읽기 및 쓰기 시간 초과 설정 : Socket_Set_Option ()을 사용하여 클라이언트 소켓의 읽기 및 쓰기 시간 초과를 설정하여 후속 데이터를 읽을 때 영구 차단을 방지하십시오.
USLEEP () CPU 사용을 줄이기 : 빈 루프를 피하면 과도한 CPU 사용이 발생합니다.
청취 소켓을 비 블로킹 및 결합 루프 폴링으로 설정하여 시간을 결정하면 Socket_accept () 차단 대기 연결의 시간 초과 제어가 달성됩니다. 동시에 연결을 수신 한 후 Socket_set_option ()을 사용하여 읽기 및 쓰기 시간 초과를 설정하여 데이터 전송 프로세스의 안정성과 보안을 보장하십시오.
이 솔루션은 간단하고 실용적이며 소켓 연결 시간 초과 수동 관리가 필요한 PHP 서버 프로그램에 매우 적합합니다.