PHP 네트워크 프로그래밍에서 Socket_select 기능은 멀티플렉싱 (I/O 멀티플렉싱)을 구현하기위한 핵심 도구입니다. 프로그램이 여러 소켓을 동시에 듣고, 읽을 수 있거나, 예외를 읽을 수 있는지, 차단 및 대기를 피하고 동시 연결을 효율적으로 처리 할 수 있습니다. 이 기사는 실제 사례를 결합하여 Socket_select 의 사용과 PHP 네트워크 프로그래밍에서의 응용 프로그램을 설명합니다.
Socket_select는 소켓 리소스 세트를 모니터링하고 읽기 및 쓸 준비가 된 소켓을 결정하는 데 사용됩니다. 프로토 타입은 다음과 같습니다.
int socket_select(array &$read, array &$write, array &$except, ?int $tv_sec, ?int $tv_usec = null)
$ 읽기 : 읽을 수 있는지 듣습니다.
$ 쓰기 : 쓰기가 가능한지 여부를 듣습니다.
예외 : 예외를 듣는 소켓 배열
$ TV_SEC 및 $ TV_USEC : 타임 아웃 (초 및 마이크로 초)
기능은 하나 이상의 소켓이 준비되거나 타임 아웃이 발생하여 소켓 수를 반환 할 때까지 블록합니다.
실제 서버 개발에서 우리는 종종 여러 클라이언트 연결이 동시에 도착하는 상황에 직면합니다. Blocking Socket_Accept를 사용하면 동시에 여러 연결을 처리 할 수 없으므로 성능 병목 현상으로 쉽게 연결할 수 있습니다. socket_select 를 통해 우리는 다음을 수행 할 수 있습니다.
여러 클라이언트 연결을 동시에 듣습니다
소켓에 데이터가있는 시간에 데이터를 읽고 유휴 상태 일 때 CPU를 차단하지 않습니다.
효율적인 이벤트 중심 모델을 구현하십시오
다음 예제는 여러 클라이언트 연결을 지원하고 모든 사람에게 메시지를 방송하는 간단한 대화방 서버를 구현합니다.
<?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);
서버는 먼저 TCP 소켓을 생성하고 포트를 바인딩하며 연결을 리터텐시킵니다.
기본 루프에는 $ $ readsockets에는 모든 클라이언트 소켓과 서버 청취 소켓이 포함되어 있습니다.
소켓을 읽을 때까지 socket_select를 호출하십시오.
서버 소켓을 읽을 수있는 경우 새 연결이 있으며 클라이언트 목록에 허용 및 추가됩니다.
클라이언트 소켓을 읽을 수 있고 데이터를 읽고 비어 있으면 연결을 닫고 메시지를 방송합니다.
CPU 공회전을 피하기 위해 비 블로킹 짧은 시간 초과 0.2 초를 사용하십시오.
Socket_Select 는 다중 연결 I/O 멀티플렉싱의 핵심이며 서버 성능 차단을 피하고 개선하지 않습니다.
Socket_Select를 사용하여 다중 클라이언트 동시 처리를 쉽게 구현할 수 있습니다.
대화방, 온라인 게임, 인스턴트 메시징 및 기타 네트워크 응용 프로그램 시나리오에 적합합니다.
PHP 네트워크 프로그래밍에 대한 자세한 튜토리얼 및 사례를 알고 싶다면 http://gitbox.net/php-network-tutourial을 방문하십시오.