PHP 소켓을 프로그래밍 할 때 Socket_set_block () 함수는 소켓을 차단 모드로 설정하는 데 사용됩니다. 차단 모드는 read ( socket_read () ), write ( socket_write () ) 또는 수신 연결 ( socket_accept () )과 같은 작업이 데이터를 읽거나 쓰여지거나 연결이 수반 될 때까지 대기한다는 것을 의미합니다. 이것이 명확하지 않은 경우, 일부 시나리오에서 socket_set_block ()을 사용하면 전체 PHP 스크립트가 "정체"하게됩니다. 즉, 프로그램은 응답없이 오랫동안 붙어 있습니다.
socket_set_block ()을 사용한 후 PHP는 차단 모드로 들어가서 소켓 작동 결과를 기다립니다. 해당 리소스 (예 : 데이터 또는 연결)가 오랫동안 반환되지 않으면 PHP 스크립트가 대기하고 후속 코드를 계속 실행하지 않습니다.
다음은 일반적인 예입니다.
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, 'gitbox.net', 80);
socket_set_block($socket); // 차단 모드로 설정합니다
// 데이터를 읽으십시오
$response = socket_read($socket, 2048);
echo $response;
socket_close($socket);
?>
서버 gitbox.net이 즉시 데이터를 반환하지 않거나 전혀 응답하지 않으면 socket_read ()가 대기하고 스크립트가 "고정"됩니다. 이러한 종류의 지연은 시간 초과 메커니즘이 트리거되지 않으면 오류를 던지지 않지만 타임 아웃 시간은 기본적으로 설정되지 않으므로 무한히 대기 할 수 있습니다.
socket_set_option ()을 사용하여 장기 차단을 방지하기 위해 읽기 및 쓰기의 시간 초과 시간을 설정하십시오.
$timeout = ['sec' => 5, 'usec' => 0]; // AS를 설정합니다5두번째
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, $timeout);
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, $timeout);
이로 인해 차단 작업이 일정 시간을 기다린 후 차단 작업이 시간을 초과하고 반환하여 오랫동안 대본이 반응하지 않도록합니다.
스크립트를 차단하지 않으려면 socket_set_nonblock ()을 사용하여 모든 소켓 작업을 즉시 다시 가져올 수 있습니다.
socket_set_nonblock($socket);
루프와 usleep ()를 사용하면 비 블로킹 대기 대기를 시뮬레이션 할 수 있습니다.
$buffer = '';
while (true) {
$chunk = @socket_read($socket, 2048);
if ($chunk === false) {
usleep(100000); // 잠100ms
continue;
} elseif ($chunk === '') {
break; // 연결이 닫힙니다
} else {
$buffer .= $chunk;
}
}
Socket_select ()는 여러 소켓이 읽고 쓸 준비가되었는지 확인할 수 있으며 차단 작업을 효율적으로 관리하는 방법입니다.
$read = [$socket];
$write = NULL;
$except = NULL;
$tv_sec = 5; // 가장 기다리고 있습니다5두번째
if (socket_select($read, $write, $except, $tv_sec) > 0) {
$response = socket_read($socket, 2048);
echo $response;
} else {
echo "Socket 시간 초과 또는 읽기 쉬운 데이터가 없습니다";
}
socket_select ()는 소켓에 실제로 읽기 전에 읽을 데이터가 있는지 여부를 결정할 수 있으며 차단 상태에 직접 입력하는 것을 피할 수 있습니다.
socket_set_block () 사용은 안전하지 않지만 컨텍스트를 매우 명확하게 제어해야합니다. 네트워크 지연 및 응답이없는 서비스 문제로 인해 영구적으로 방해받은 스크립트를 피하기 위해 비 차단 모드를 사용하거나 차단 모드에서 시간 초과 시간을 명시 적으로 설정하는 것이 좋습니다.
실시간 응답 또는 동시 처리가 필요한 시나리오의 경우, Socket_set_nonBlock ()을 사용하거나 Socket_Select () 와 결합하여 프로그램의 실행 흐름을 유연하게 제어하는 것이 좋습니다. 이것은 프로그램 견고성을 향상시킬뿐만 아니라 시스템 응답 효율을 크게 향상시킵니다.