네트워크 프로그래밍, 특히 긴 연결과 관련된 시나리오에서 서버는 여러 클라이언트 연결을 지속적으로 듣고 관리해야합니다. PHP는 풍부한 소켓 기능을 제공합니다. Socket_accept ()는 클라이언트 연결 요청을받는 데 사용되는 중요한 기능 중 하나입니다. 이 기사는 Socket_accept ()를 사용하여 긴 연결 시나리오에서 효율적인 연결 관리를 달성하는 방법을 자세히 소개합니다.
긴 연결은 클라이언트가 서버와 연결을 설정 한 후 연결이 열려 있으며 연결이 명시 적으로 닫힐 때까지 두 당사자가 계속 통신 할 수 있음을 의미합니다. 짧은 연결과 비교할 때 긴 연결은 연결을 자주 설정하고 닫는 오버 헤드를 줄이고 즉각적인 커뮤니케이션 및 메시지 푸시와 같은 시나리오에 더 적합합니다.
Socket_accept ()는 청취 소켓의 연결 요청을 수락하고 클라이언트와의 통신을 위해 새로운 소켓 리소스를 반환하는 데 사용됩니다. 일반적인 사용법은 다음과 같습니다.
$serverSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($serverSocket, '0.0.0.0', 8080);
socket_listen($serverSocket);
while (true) {
$clientSocket = socket_accept($serverSocket);
if ($clientSocket === false) {
// 처리 오류
continue;
}
// 클라이언트 요청을 처리합니다
}
차단 문제
socket_accept () 는 차단 호출입니다. 연결 요청이 없으면 프로그램이 여기에서 중지되어 여러 클라이언트의 동시 처리에 영향을 미칩니다.
다중 연결 관리 <br> 긴 연결은 단일 스레드 차단을 피하기 위해 여러 클라이언트 연결의 읽기 및 쓰기 작업을 동시에 관리해야합니다.
자원 직업 <br> 너무 많은 긴 연결이 시스템 리소스를 점유하고 합리적인 릴리스 및 유지 보수가 필요합니다.
연결을 차단하고 대기하지 않도록 socket_set_nonblock () 을 통해 소켓을 비 블로킹 모드로 설정하십시오.
socket_set_nonblock($serverSocket);
이 시점에서 socket_accept ()는 차단되지 않으며 연결 요청이 없으면 False가 반환됩니다.
socket_select ()를 사용하면 여러 소켓의 읽기 및 쓸 수 있으며 동시에 비 블로킹 모드와 결합하여 여러 긴 연결을 효율적으로 처리 할 수 있습니다.
샘플 코드 :
$serverSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($serverSocket, '0.0.0.0', 8080);
socket_listen($serverSocket);
socket_set_nonblock($serverSocket);
$clients = [];
while (true) {
$readSockets = $clients;
$readSockets[] = $serverSocket;
$write = $except = null;
$numChangedSockets = socket_select($readSockets, $write, $except, 0, 500000);
if ($numChangedSockets === false) {
// 오류 처리
break;
} elseif ($numChangedSockets > 0) {
// 새로운 연결이 있는지 듣습니다
if (in_array($serverSocket, $readSockets)) {
$newClient = socket_accept($serverSocket);
if ($newClient !== false) {
socket_set_nonblock($newClient);
$clients[] = $newClient;
}
// 가공 된 청취 소켓을 제거하십시오
$key = array_search($serverSocket, $readSockets);
unset($readSockets[$key]);
}
// 클라이언트 데이터를 처리합니다
foreach ($readSockets as $clientSocket) {
$data = @socket_read($clientSocket, 1024, PHP_NORMAL_READ);
if ($data === false || $data === '') {
// 클라이언트는 연결을 닫습니다
$key = array_search($clientSocket, $clients);
socket_close($clientSocket);
unset($clients[$key]);
} else {
$data = trim($data);
if ($data) {
// 这里클라이언트 데이터를 처리합니다
socket_write($clientSocket, "서버가 접수되었습니다: $data\n");
}
}
}
}
// 심장 박동 감지는 여기에 추가 할 수 있습니다、시간 초과 처리 및 기타 논리
}
심장 박동 메커니즘 : 정기적으로 심장 박동 패킷을 보내고 고객의 생존을 감지하고 시간이 지남에 따라 유효하지 않습니다.
연결 풀 : 자원 소진을 피하기 위해 최대 연결 수를 제한합니다.
타임 아웃 단절 : 오랫동안 데이터 상호 작용이없는 닫기 연결.
비 차단 모드를 설정하고 Socket_Select () 멀티플렉싱 기술을 결합함으로써 PHP는 Socket_accept ()를 효율적으로 사용하여 긴 연결을 관리하여 많은 클라이언트 연결을 동시에 처리 할 수 있습니다. 합리적으로 연결 유지 관리 및 리소스 관리 메커니즘을 설계하면 장기 연결 시나리오에서 안정적인 서버 작동을 보장하고 성능을 향상시킬 수 있습니다.