현재 위치: > 최신 기사 목록> PHP 네트워크 프로그래밍에서 Socket_select의 실제 응용 프로그램

PHP 네트워크 프로그래밍에서 Socket_select의 실제 응용 프로그램

gitbox 2025-05-28

PHP 네트워크 프로그래밍에서 Socket_select 기능은 멀티플렉싱 (I/O 멀티플렉싱)을 구현하기위한 핵심 도구입니다. 프로그램이 여러 소켓을 동시에 듣고, 읽을 수 있거나, 예외를 읽을 수 있는지, 차단 및 대기를 피하고 동시 연결을 효율적으로 처리 할 수 ​​있습니다. 이 기사는 실제 사례를 결합하여 Socket_select 의 사용과 PHP 네트워크 프로그래밍에서의 응용 프로그램을 설명합니다.


1. Socket_select의 기본 원칙과 함수

Socket_select는 소켓 리소스 세트를 모니터링하고 읽기 및 쓸 준비가 된 소켓을 결정하는 데 사용됩니다. 프로토 타입은 다음과 같습니다.

 int socket_select(array &$read, array &$write, array &$except, ?int $tv_sec, ?int $tv_usec = null)
  • $ 읽기 : 읽을 수 있는지 듣습니다.

  • $ 쓰기 : 쓰기가 가능한지 여부를 듣습니다.

  • 예외 : 예외를 듣는 소켓 배열

  • $ TV_SEC$ TV_USEC : 타임 아웃 (초 및 마이크로 초)

기능은 하나 이상의 소켓이 준비되거나 타임 아웃이 발생하여 소켓 수를 반환 할 때까지 블록합니다.


2. 실제 개발에서 socket_select의 역할

실제 서버 개발에서 우리는 종종 여러 클라이언트 연결이 동시에 도착하는 상황에 직면합니다. Blocking Socket_Accept를 사용하면 동시에 여러 연결을 처리 할 수 ​​없으므로 성능 병목 현상으로 쉽게 연결할 수 있습니다. socket_select 를 통해 우리는 다음을 수행 할 수 있습니다.

  • 여러 클라이언트 연결을 동시에 듣습니다

  • 소켓에 데이터가있는 시간에 데이터를 읽고 유휴 상태 일 때 CPU를 차단하지 않습니다.

  • 효율적인 이벤트 중심 모델을 구현하십시오


3. PHP 네트워크 프로그래밍 실용 사례 : 다중 클라이언트 채팅방 서버

다음 예제는 여러 클라이언트 연결을 지원하고 모든 사람에게 메시지를 방송하는 간단한 대화방 서버를 구현합니다.

 <?php
// 만들다TCP Socket
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($server, "0.0.0.0", 12345);
socket_listen($server);

$clients = [];
echo "채팅방 서버 시작,포트를 들어보세요12345...\n";

while (true) {
    // 청취 배열을 만듭니다,서버 포함socket그리고 모든 고객socket
    $readSockets = $clients;
    $readSockets[] = $server;

    // 사용socket_select가독성을 기다리십시오socket
    $write = $except = null;
    $numChangedSockets = socket_select($readSockets, $write, $except, 0, 200000);

    if ($numChangedSockets === false) {
        echo "socket_select 오류가 발생했습니다\n";
        break;
    } elseif ($numChangedSockets > 0) {
        // 새로운 연결을 듣습니다
        if (in_array($server, $readSockets)) {
            $newClient = socket_accept($server);
            if ($newClient !== false) {
                $clients[] = $newClient;
                $welcomeMsg = "채팅방에 오신 것을 환영합니다!\n";
                socket_write($newClient, $welcomeMsg, strlen($welcomeMsg));
                echo "새 클라이언트에 가입하십시오,현재 연결 번호:" . count($clients) . "\n";
            }
            // ~에서readSockets제거server socket,반복 처리를 방지하십시오
            $key = array_search($server, $readSockets);
            unset($readSockets[$key]);
        }

        // 클라이언트가 보낸 프로세스 메시지
        foreach ($readSockets as $sock) {
            $data = @socket_read($sock, 2048, PHP_NORMAL_READ);
            if ($data === false || $data === '') {
                // 클라이언트는 연결을 닫습니다
                $key = array_search($sock, $clients);
                socket_close($sock);
                unset($clients[$key]);
                echo "클라이언트 단절,현재 연결 번호:" . count($clients) . "\n";
                continue;
            }
            $data = trim($data);
            if ($data) {
                echo "메시지를 받았습니다: $data\n";
                // 모든 고객에게 메시지를 방송합니다
                foreach ($clients as $client) {
                    if ($client != $sock) {
                        socket_write($client, "사용자가 말했다: $data\n");
                    }
                }
            }
        }
    }
}
socket_close($server);

4. 코드 분석

  • 서버는 먼저 TCP 소켓을 생성하고 포트를 바인딩하며 연결을 리터텐시킵니다.

  • 기본 루프에는 $ $ readsockets에는 모든 클라이언트 소켓과 서버 청취 소켓이 포함되어 있습니다.

  • 소켓을 읽을 때까지 socket_select를 호출하십시오.

  • 서버 소켓을 읽을 수있는 경우 새 연결이 있으며 클라이언트 목록에 허용 및 추가됩니다.

  • 클라이언트 소켓을 읽을 수 있고 데이터를 읽고 비어 있으면 연결을 닫고 메시지를 방송합니다.

  • CPU 공회전을 피하기 위해 비 블로킹 짧은 시간 초과 0.2 초를 사용하십시오.


5. 요약

  • Socket_Select 는 다중 연결 I/O 멀티플렉싱의 핵심이며 서버 성능 차단을 피하고 개선하지 않습니다.

  • Socket_Select를 사용하여 다중 클라이언트 동시 처리를 쉽게 구현할 수 있습니다.

  • 대화방, 온라인 게임, 인스턴트 메시징 및 기타 네트워크 응용 프로그램 시나리오에 적합합니다.


PHP 네트워크 프로그래밍에 대한 자세한 튜토리얼 및 사례를 알고 싶다면 http://gitbox.net/php-network-tutourial을 방문하십시오.