PHP를 사용하여 소켓 기반 네트워크 애플리케이션을 개발할 때 개발자는 종종 Socket_accept () 및 Socket_set_block ()의 두 기능과 접촉합니다. 두 기능 모두 PHP 소켓 확장에 속하지만 사용과 밀접한 관련이 있습니다. 그들의 공동 작업 메커니즘을 이해하면 소켓의 동작을보다 정확하게 제어하고 네트워크 통신의 신뢰성과 효율성을 향상시키는 데 도움이됩니다.
이 두 기능의 협력을 탐색하기 전에 먼저 기본 기능을 이해해 봅시다.
Socket_accept (Resource $ 소켓) : Resource | False
이 기능은 청취 소켓의 연결 요청을 수락하는 데 사용됩니다. 연결 요청이 없으면 동작은 소켓의 차단 패턴에 따라 다릅니다.
socket_set_block (Resource $ 소켓) : bool
이 함수는 소켓을 차단 모드로 설정합니다. 차단 모드에서는 관련 소켓 작업 ( Socket_Accept , Socket_read 등)이 데이터 또는 연결이 발생할 때까지 대기합니다.
socket_set_block () 의 반대는 socket_set_nonblock () 으로, 데이터 또는 연결이 있는지 여부에 관계없이 소켓 작동이 즉시 돌아옵니다.
기본적으로 PHP에서 생성 된 소켓은 차단 모드에 있습니다. 즉, socket_accept ()는 클라이언트 연결이있을 때까지 차단하고 대기합니다. 즉, 다음 코드를 실행하는 경우 :
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 12345);
socket_listen($socket);
$client = socket_accept($socket);
echo "Connection accepted";
클라이언트 연결이 없으면 프로그램이 연결이 발생할 때까지 Socket_Accept () 호출에서 중지됩니다.
이제 socket_set_block ()을 소개하고 소켓을 차단 모드로 명시 적으로 설정합니다 (기본적으로 차단되지만 명백한 설정은 모드를 변경 한 이전 작업으로 인해 코드가 오류를 방지 할 수 있습니다).
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_block($socket); // 명시 적으로 차단 모드로 설정됩니다
socket_bind($socket, '0.0.0.0', 12345);
socket_listen($socket);
$client = socket_accept($socket);
echo "Connection accepted";
이 시점에서 Socket_accept () 의 동작은 변하지 않습니다. 클라이언트 연결이있을 때까지 여전히 차단됩니다.
그러나 우리가 socket_set_nonblock ()을 사용하는 경우 여기에 있습니다.
socket_set_nonblock($socket);
그런 다음 socket_accept ()가 호출되면 연결 요청이 없으면 즉시 false를 반환하고 socket_last_error ()는 eagain 또는 ewouldBlock 로 인해 확인 될 수 있으므로 연결의 비 블로킹 수신 논리를 구현합니다.
socket_set_block () 과 socket_accept () 간의 협업은 소켓의 작동 모드를 설정하여 socket_accept () 의 차단 동작을 결정함으로써 본질적으로 결정됩니다. 이 설정은 프로그램의 제어 흐름이 동기식 (차단)인지 비동기식 (비 블로킹)인지 여부를 결정합니다.
예를 들어, 고성능 서버를 작성할 때는 차단되지 않은 소켓을 사용하고 Socket_Select ()를 결합하여 여러 연결 요청을 듣습니다.
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($socket);
socket_bind($socket, '0.0.0.0', 12345);
socket_listen($socket);
$clients = [];
while (true) {
$read = [$socket];
$write = $except = null;
if (socket_select($read, $write, $except, 1) > 0) {
$client = socket_accept($socket);
if ($client !== false) {
$clients[] = $client;
echo "Client connected\n";
}
}
// 다른 논리를 처리하십시오
}
이 방법을 사용하면 Socket_Accept () 에서 차단하고 대기하지 않고 루프에서 여러 소켓을 동시에 처리 할 수 있습니다.
socket_set_block () 소켓 블록이 작동하는지 여부를 결정하고 Socket_accept ()는 이 설정의 영향을받는 특정 작업입니다. 소켓이 차단 모드 인 경우 Socket_accept ()는 연결을 기다립니다. 차단 모드에서는 즉시 돌아옵니다. 이 둘의 공동 작업을 통해 실제 요구에 따라 동기 또는 비동기 네트워크 서비스 프로그램을 작성하여 유연성이 향상됩니다.
그들의 관계를 이해하면 안정된 소켓 서비스를 작성하는 데 도움이 될뿐만 아니라, 대기 시간이 저조한 네트워크 애플리케이션을 구축하기위한 기초가됩니다.
관련 예제는 https://gitbox.net/socket-examples 를 참조하십시오.