현재 위치: > 최신 기사 목록> 비 차단 청취에서 Socket_set_Block 상태를 임시로 전환하는 방법

비 차단 청취에서 Socket_set_Block 상태를 임시로 전환하는 방법

gitbox 2025-05-26

PHP에서 네트워크 프로그래밍에 소켓을 사용할 때는 비 블로킹 모드가 동시 처리 기능을 향상시킬 수 있으며 이벤트 중심 또는 다중 서버를 구현하는 핵심입니다. 그러나 때로는 대형 데이터 패킷을 전체로 읽거나 클라이언트가 완전한 핸드 셰이크 데이터를 보내기를 기다리는 등 특정 "대기 대기"작업을 완료하기 위해 소켓을 차단 상태로 임시로 설정해야합니다.

다행스럽게도 PHP는 Socket_set_Block ()Socket_set_nonBlock () 의 ​​두 가지 기능을 제공하며 차단 및 비 블로킹 모드 사이에서 쉽게 전환 할 수 있습니다.

이 기사는 특정 TCP 서버 예제를 결합하여 비 차단 청취에서 소켓을 일시적으로 차단 상태로 전환하고 작업을 완료 한 후 비 블로킹 상태를 복원하는 방법을 보여줍니다.

샘플 시나리오

비 차단 TCP 서버를 빌드하고 클라이언트 연결을 듣고 클라이언트 연결을 수신 한 후 연결을 차단 모드로 일시적으로 전환하고 클라이언트의 데이터를 읽은 다음 완료 후 비 블로킹 모드로 다시 전환합니다.

다음은 전체 코드입니다.

<코드> <? php

$ host = '0.0.0.0';
$ port = 12345;

// 소켓 생성
$ server = socket_create (af_inet, sock_stream, sol_tcp);
socket_set_option ($ server, sol_socket, so_reuseaddr, 1);

// 바인딩과 듣기
socket_bind ($ server, $ host, $ port);
socket_listen ($ server);

// 블로킹이 아닌 것으로 설정합니다
socket_set_nonblock ($ server);

echo "{$ host} : {$ port} ... \ n"에서 듣는 서버 청취;

$ clients = [];

while (true) {
// 연결 수락 (비 블로킹)
$ client = @socket_accept ($ server);
if ($ client! == false) {
Echo "새로운 클라이언트 연결. \ n";
// 클라이언트 목록에 추가하십시오
$ client [] = $ client;

     // 클라이언트를 비 블로킹으로 설정하십시오
    socket_set_nonblock($client);
}

foreach ($clients as $index => $sock) {
    $buffer = '';

    // 전체 읽기를 보장하기 위해 일시적으로 블록으로 설정했습니다(예를 들어, 고정 된 길이를 읽거나 플래그까지)
    socket_set_block($sock);

    $bytes = @socket_recv($sock, $buffer, 1024, MSG_DONTWAIT);

    // 비 차단으로 되돌아갑니다
    socket_set_nonblock($sock);

    if ($bytes === false || $bytes === 0) {
        // 클라이언트 연결이 끊어졌습니다
        echo "Client disconnected.\n";
        socket_close($sock);
        unset($clients[$index]);
        continue;
    }

    // 출력 읽기 데이터
    echo "Received: " . trim($buffer) . "\n";

    // 샘플 응답
    $response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello from server!\n";
    socket_write($sock, $response);
}

// 약간의 지연 회피 CPU 가득한
usleep(100000);

}

socket_close ($ server);
?>
</코드>

시나리오 설명을 사용합니다

위의 코드에서 청취 소켓 ($ Server)은 차단하지 않으므로 socket_accept () 에서 차단하지 않습니다. 새 연결이 수락 될 때마다 새 클라이언트를 차단하지 않도록 설정합니다. 그러나 수신 데이터를 처리하는 부분에서는 Socket_Recv ()가 기대하는 데이터를 완전히 수신하고 데이터 불완전 성을 피할 수 있으므로 클라이언트 소켓을 블록 모드로 적극적으로 전환합니다.

이것은 매우 일반적인 혼합 사용 방법이며 많은 시나리오 (예 : 프로토콜 핸드 셰이크 단계)에서 특히 중요합니다. 예를 들어, 클라이언트가 처음으로 고정 헤더 정보를 포함해야한다는 규정을 규정하는 간단한 프로토콜을 설계했으며, 계속 처리되기 전에 서버는 완전히 수신해야합니다. 현재 블록 읽기를 사용하는 것은 매우 의미가 있습니다.

주목해야 할 것

  • 모드를 전환 할 때주의하십시오 : 비 차단 프로세스에서 일시적으로 읽기 차단 사용은 "강제 대기"방법입니다. 편리하지만 클라이언트가 데이터를 보내지 않으면 서버가 고정됩니다. 시간 초과 메커니즘 또는 사전 설정 데이터 길이와 일치하는 것이 좋습니다.

  • 단기 차단에 적합 :이 유형의 모드 스위칭은 특정 작업을 차단 해야하는 상황에 적합하며 통신 프로세스 전체에서 차단을 사용하는 것이 좋습니다.

결론

socket_set_block ()socket_set_nonblock ()을 사용하여 PHP 소켓 프로그래밍을보다 유연하게 만듭니다. 처리 로직에 따라 적절한 차단 모드를 유연하게 선택하여 효율성과 무결성을 고려할 수 있습니다.

더 많은 소켓 프로그래밍 관행 및 예를 보려면 문서를 참조하거나 자원 플랫폼을 방문하십시오.

https://gitbox.net/php-socket-guide