Sockets socket_select

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

socket_select — 지정된 시간 초과로 지정된 소켓 배열에서 select() 시스템 호출을 실행합니다.


설명

socket_select(
    ?array &$read,
    ?array &$write,
    ?array &$except,
    ?int $seconds,
    int $microseconds = 0
): int|false
                

socket_select()는 소켓 배열을 수락하고 상태가 변경될 때까지 기다립니다. BSD 소켓 배경을 가지고 오는 사람들은 그 소켓 배열이 사실상 소위 파일 디스크립터 세트라는 것을 인식할 것입니다. 3개의 독립적인 소켓 어레이가 감시됩니다.


매개변수

read
read 배열에 나열된 소켓은 문자를 읽을 수 있는지 확인하기 위해 감시됩니다(더 정확하게는 읽기가 차단되지 않는지 확인하기 위해 - 특히 소켓은 파일 끝에서도 준비되어 있습니다. 이 경우 socket_read()는 길이가 0인 문자열을 반환합니다).
write
write 배열에 나열된 소켓은 쓰기가 차단되지 않는지 확인하기 위해 감시됩니다.
except
except 배열에 나열된 소켓은 예외를 감시합니다.
seconds
secondsmicroseconds는 함께 timeout 매개변수를 형성합니다. timeoutsocket_select() 반환 전에 경과된 시간의 상한입니다. seconds는 0일 수 있으므로 socket_select()가 즉시 반환됩니다. 이것은 폴링에 유용합니다. secondsnull이면(시간 초과 없음) socket_select()가 무기한 차단될 수 있습니다.
microseconds

경고 종료 시 배열이 수정되어 실제로 어떤 소켓이 상태를 변경했는지 나타냅니다.

모든 배열을 socket_select()에 전달할 필요는 없습니다. 이를 생략하고 대신 빈 배열이나 null을 사용할 수 있습니다. 또한 해당 배열은 참조로 전달되고 socket_select()가 반환된 후에 수정된다는 점을 잊지 마십시오.

메모:

현재 Zend 엔진의 한계로 인해 null과 같은 상수 수정자를 매개변수로 직접 전달하는 것은 불가능합니다. 대신 임시 변수 또는 가장 왼쪽 멤버가 임시 변수인 표현식을 사용하십시오.

예제 #1 socket_select()와 함께 null 사용

                    
<?php
$e = NULL;
socket_select($r, $w, $e, 0);
?>
                    
                  

반환 값

성공 시 socket_select()는 수정된 배열에 포함된 소켓 수를 반환합니다. 흥미로운 일이 발생하기 전에 시간 초과가 만료되면 0이 될 수 있습니다. 오류 발생 시 false가 반환됩니다. 오류 코드는 socket_last_error()로 검색할 수 있습니다.

메모:

오류를 확인할 때 === 연산자를 사용해야 합니다. socket_select()가 0을 반환할 수 있으므로 ==와 비교하면 true로 평가됩니다.

예제 #2 socket_select()의 결과 이해하기

                    
<?php
$e = NULL;
if (false === socket_select($r, $w, $e, 0)) {
    echo "socket_select() failed, reason: " .
        socket_strerror(socket_last_error()) . "\n";
}
?>
                    
                  

Examples

예제 #3 socket_select() 예제

                  
<?php
/* Prepare the read array */
$read   = array($socket1, $socket2);
$write  = NULL;
$except = NULL;
$num_changed_sockets = socket_select($read, $write, $except, 0);

if ($num_changed_sockets === false) {
    /* Error handling */
} else if ($num_changed_sockets > 0) {
    /* At least at one of the sockets something interesting happened */
}
?>
                  
                

메모

메모:

일부 소켓 구현은 매우 신중하게 처리해야 합니다. 몇 가지 기본 규칙:

  • 항상 시간 초과 없이 socket_select()를 사용하려고 시도해야 합니다. 사용 가능한 데이터가 없으면 프로그램에서 아무 작업도 수행하지 않아야 합니다. 시간 초과에 의존하는 코드는 일반적으로 이식 가능하지 않고 디버그하기 어렵습니다.
  • socket_select() 호출 후 결과를 확인하고 적절하게 응답하지 않으려면 어떤 세트에도 소켓을 추가하지 않아야 합니다. socket_select()가 반환된 후 모든 배열의 모든 소켓을 확인해야 합니다. 쓰기에 사용할 수 있는 모든 소켓에 기록해야 하고 읽기에 사용할 수 있는 소켓을 읽어야 합니다.
  • 소켓에 읽기/쓰기가 배열에서 반환되는 경우 요청한 데이터의 전체 양을 반드시 읽거나 쓸 필요는 없다는 점에 유의하십시오. 단일 바이트만 읽고 쓸 수 있도록 준비하십시오.
  • 대부분의 소켓 구현에서는 예외 배열에서 catch되는 유일한 except가 소켓에서 수신된 범위를 벗어난 데이터라는 것이 일반적입니다.

기타