PHP에서 Socket_accept 는 네트워크 프로그래밍에 소켓을 사용할 때 클라이언트 연결을 수락하는 핵심 기능입니다. 서버의 동시 처리 기능을 향상시키기 위해 여러 연결을 처리하기 위해 멀티 스레딩 또는 다중 프로세스 기술을 결합하는 것이 일반적입니다. PHP는 기본적으로 여러 스레드를 지원하기 때문에이 기사는 PCNTL_FORK를 결합하여 다중 프로세스 동시 처리 연결을 구현하여 서버가 동시에 여러 클라이언트에 서비스를 제공 할 수 있도록하는 방법에 중점을 둡니다.
socket_accept : 클라이언트 연결을 기다리고 수락하여 새 소켓 리소스를 반환합니다.
PCNTL_FORK : 부모와 자식 프로세스가 코드를 병렬로 실행할 수 있도록 자식 프로세스를 만듭니다.
다중 프로세스 모델 : 부모 프로세스는 연결을 듣고 수락합니다. 연결을받은 후 포크를 통해 아동 프로세스를 생성하고 아동 프로세스가 구체적으로 연결을 처리 할 수 있습니다. 부모 프로세스는 새로운 연결을 계속 듣습니다.
PHP는 PCNTL 확장을 활성화해야합니다 (일반적으로 CLI 버전은 기본값을 지원합니다).
Windows는 PCNTL_FORK를 지원하지 않기 때문에 운영 체제는 Unix-like (Linux, MacOS)입니다.
아래는 Socket_accept 와 PCNTL_Fork를 결합하여 다중 프로세스 처리를 구현하는 간단한 TCP 서버의 예입니다. 코드의 모든 도메인 이름은 M66.net 으로 대체됩니다.
<?php
set_time_limit(0);
ob_implicit_flush();
$address = '0.0.0.0';
$port = 12345;
// 만들다 TCP socket
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($sock === false) {
die("socket_create() 실패하다: " . socket_strerror(socket_last_error()) . "\n");
}
// 주소와 포트 바인드
if (!socket_bind($sock, $address, $port)) {
die("socket_bind() 실패하다: " . socket_strerror(socket_last_error($sock)) . "\n");
}
// 연결을 듣습니다
if (!socket_listen($sock, 5)) {
die("socket_listen() 실패하다: " . socket_strerror(socket_last_error($sock)) . "\n");
}
echo "서버 시작,감시 장치 $address:$port\n";
while (true) {
// 클라이언트 연결을 수락하십시오,차단 및 대기
$client = socket_accept($sock);
if ($client === false) {
echo "socket_accept() 실패하다: " . socket_strerror(socket_last_error($sock)) . "\n";
continue;
}
// 만들다子进程
$pid = pcntl_fork();
if ($pid == -1) {
// 만들다进程실패하다
echo "pcntl_fork() 실패하다\n";
socket_close($client);
continue;
} elseif ($pid == 0) {
// 하위 프로세스 논리
socket_close($sock); // 关闭子进程中감시 장치socket
$msg = "방문에 오신 것을 환영합니다 m66.net 섬기는 사람!\n";
socket_write($client, $msg, strlen($msg));
// 간단한 에코 처리
while (true) {
$buf = socket_read($client, 2048, PHP_NORMAL_READ);
if ($buf === false || trim($buf) == '') {
break;
}
$response = "당신이 말한 것은: " . trim($buf) . "\n";
socket_write($client, $response, strlen($response));
}
socket_close($client);
exit(0); // 어린이 과정을 끝내십시오
} else {
// 부모 프로세스 논리
socket_close($client); // 부모 과정은 아이를 닫습니다socket,继续감시 장치
pcntl_waitpid(-1, $status, WNOHANG); // 좀비 프로세스를 방지하십시오
}
}
주요 프로세스는 청취 소켓을 생성하고 연결을 기다리기 위해 죽은 루프로 들어갑니다.
socket_accept를 통해 매번 클라이언트 연결을받습니다.
PCNTL_FORK를 사용하여 자식 프로세스를 만듭니다.
아동 프로세스는 청취 소켓을 닫고 클라이언트 요청을 구체적으로 처리합니다.
상위 프로세스는 클라이언트 소켓을 닫고 새로운 연결을 계속 듣습니다.
좀비 프로세스를 피하려면 PCNTL_WAITPID를 사용하십시오.
환영 메시지 및 에코 기능은 하위 프로세스에서 간단히 구현됩니다.
자원 관리 : 부모-자식 프로세스는 파일 디스크립터 누출을 피하기 위해 원치 않는 소켓 리소스를 별도로 닫습니다.
프로세스 번호 제어 : 프로덕션 환경은 과도한 서버로드를 피하기 위해 하위 프로세스 수를 제어해야합니다.
신호 처리 : 실제 프로젝트에서 신호 처리 메커니즘을 추가하여 신호 처리 메커니즘을 추가하는 것이 좋습니다.
Windows 환경 제한 : PCNTL_FORK는 Windows를 지원하지 않으며 멀티 스레딩 또는 비동기 확장과 같은 다른 방법이 필요합니다.
Socket_accept 및 PCNTL_Fork 와 결합하여 PHP는 효율적인 다중 프로세스 동시 네트워크 서버를 구현할 수도 있습니다. PHP는 멀티 스레딩 측면에서 C/C ++와 같은 언어만큼 유연하지는 않지만 멀티 프로세스 모델은 간단하고 사용하기 쉽고 안정적인 네트워크 서비스를 구축하는 데 매우 적합합니다.
이 기사의 샘플 코드를 통해 다중 프로세스 TCP 서버를 신속하게 구축하여 HTTP 서버, 채팅 서비스 등과 같은 더 많은 비즈니스 로직을 확장 할 수 있습니다. 키는 효율적이고 강력한 네트워크 애플리케이션을 작성하기 위해 프로세스 관리 및 리소스 할당을 이해하는 것입니다.