PHP+Socket 시리즈의 IO 다중화 및 웹서버 구현
이 기사는 주로 IO 멀티플렉싱을 소개하는 php+socket에 대한 관련 지식과 php+socket이 웹 서버를 구현하는 방법을 제공합니다. 관심 있는 친구들은 아래를 살펴보시면 모두에게 도움이 되길 바랍니다.
PHP 네이티브 소켓 IO 다중화 및 웹 서버 구현
multiplexing
이전글 간단한 서버-클라이언트 통신은 네이티브 소켓을 통해 이루어지지만, 클라이언트가 여러 개인 경우 클라이언트가 연결되면 서버는 첫 번째 클라이언트의 요청만 처리할 수 있지만 후속 클라이언트에 서비스를 제공할 수 없는 이유는 IO 모델이 차단되고 동시에 하나의 클라이언트만 사용할 수 있기 때문입니다. 액세스하려면 두 가지 주요 솔루션이 있습니다. 이 문제 해결:
- N 클라이언트 사용을 간단히 구현하는 IO 다중화 메커니즘 하나의 네트워크 케이블을 통한 동시 액세스
- 동시 멀티플렉싱은
select
와epoll
이라는 두 가지 모델로 나뉩니다. 일반적인 소프트웨어에서Apache
는select
모델을 사용합니다. ,nginx
는epoll
모델을 사용합니다. PHP에는select
모델이 내장되어 있으며 해당 함수는socket_select
입니다. 멀티플렉싱은 먼저 http 서버구문
을 구현하는 기초입니다. 이 기사에서는 PHP 네이티브 소켓에select
모델을 구현하는 내장socket_select
함수가 있음을 소개했습니다. 해당 구문은 다음과 같습니다.
socket_select( array &$read, array &$write, array &$except, int $seconds [, int $microseconds = 0]): int|false
매개변수
readselect
与 epoll
,常见的软件中,Apache
使用了 select
模型,nginx
则使用 epoll
模型。在 php 中内置了 select
模型,对应的函数为 socket_select
,多路复用是实现 http 服务器的基础
语法
在前文中我们介绍了 php 原生 socket 内置了 socket_select
函数实现了 select
模型,其语法如下:
<?php // 创建套接字 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); // 设置 ip 被释放后立即可使用 socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, true); // 绑定ip与端口 socket_bind($socket, 0, 8888); // 开始监听 socket_listen($socket); $sockets[] = $socket; while (true) { $tmp_sockets = $sockets; socket_select($tmp_sockets, $write, $except, null); foreach ($tmp_sockets as $sock) { // 如果当前套接字等于 socket_create 创建的套接字,说明是有新的连接或有新的断开连接 if ($sock == $socket) { $conn_sock = socket_accept($socket); $sockets[] = $conn_sock; socket_getpeername($conn_sock, $ip, $port); echo '请求ip: ' . $ip . '端口: ' . $port . PHP_EOL; } else { // 否则说明是之前连接的客户端发来消息 $msg = socket_read($sock, 10240); socket_write($sock, strtoupper($msg)); echo $msg; } } }
参数
read
服务端监听的套接字资源,当他有变化(即收到新的消息或有客户端连接、断开)时,
socket_select
函数才会返回(否则继续阻塞),同时修改该变量为当前发生事件(收到消息或有客户端连接、断开)的套接字资源列表,并继续向下执行。write
监听是否有客户端写数据,传入
null
则代表不关心是否有写变化except
套接字内要排除的元素,传入
null
是 「监听」 全部seconds
秒和微秒一起构成超时参数。如果传入
null
则会阻塞,为 0 非阻塞,如果是 >0 则为最大阻塞时间microseconds
优化
我们在 上篇文章 简单实现了 socket 服务端监听与客户端的连接,接下来我们在服务端监听代码的基础上通过多路复用优化代码:
<?php // 创建套接字 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); // 设置 ip 被释放后立即可使用 socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, true); // 绑定ip与端口 socket_bind($socket, 0, 8888); // 开始监听 socket_listen($socket); $sockets[] = $socket; while (true) { $tmp_sockets = $sockets; socket_select($tmp_sockets, $write, $except, null); foreach ($tmp_sockets as $sock) { if ($sock == $socket) { $conn_sock = socket_accept($socket); $sockets[] = $conn_sock; } else { $msg = socket_read($sock, 10240); var_dump($msg); if ($msg == '') return; $output = '<h1 id="this-nbsp-is-nbsp-php-nbsp-worker">this is php worker</h1>'; $len = strlen($output); $response = "HTTP/1.1 200 OK\r\n"; $response .= "content-type: text/html\r\n"; $response .= "server: php socket\r\n"; $response .= "Content-Length: {$len}\r\n\r\n"; $response .= $output; socket_write($sock, $response); } } }
在本示例中 socket_select
函数会阻塞当前进程,当 $tmp_sockets
数组内的 socket 资源有新的客户端连接或断开或收到新消息时,会将 $tmp_sockets
数组修改为当前活跃的 socket 资源,随后通过遍历该数组处理业务逻辑
使用socket实现简易http服务器
http 协议是在 socket 的基础上规定了指定的数据格式,所以我们只需在 socket_write
时按照格式发送数据,浏览器就可正常响应请求
GET / HTTP/1.1 Host: 124.222.**.**:8888 Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: jenkins-timestamper-offset=-28800000; _ga=GA1.1.1403944751.1652010033; _ga_2GM6102E19=GS1.1.1652802985.7.1.1652803014.0
在服务端运行此示例,随后在浏览器访问 ip:8888
,可以看到如下:
同时服务端会输出如下内容:
rrreee该内容即为用户端请求原始数据,可解析此数据并根据请求做出响应,比如使用 file_get_content
소켓_선택
함수는 반환할 것이며(그렇지 않으면 계속 차단됩니다) 동시에 현재 이벤트(수신된 메시지 또는 클라이언트 연결 또는 연결 끊김)의 소켓 리소스 목록에 대한 변수를 수정하고 계속 실행합니다. 하향의. 클라이언트가 데이터를 쓰는지 여부를 모니터링합니다. null
을 전달하면 쓰기 변경 사항이 있는지 상관하지 않는다는 뜻입니다
Except code>🎜🎜 소켓에서 제외될 요소, <code>null
전달은 "수신"입니다. 모두 🎜🎜🎜🎜초
🎜🎜초와 마이크로초를 함께 구성합니다. 시간 초과 매개변수. null
이 전달되면 차단되고, 0이면 차단되지 않습니다.>0이면 최대 차단 시간이 됩니다🎜🎜🎜🎜마이크로초
🎜🎜🎜최적화
🎜우리는 이전 기사🎜 서버는 클라이언트와의 연결을 모니터링합니다. 다음으로 서버 모니터 코드를 기반으로 멀티플렉싱을 통해 코드를 최적화합니다. 🎜rrreee🎜이 예에서는socket_select
함수는 $tmp_sockets
배열의 소켓 리소스에 새로운 클라이언트 연결 또는 연결 끊김이 있거나 새 메시지를 수신할 때 $tmp_sockets
배열을 차단합니다. 현재 활성 소켓 리소스로 수정한 다음 배열을 순회하여 비즈니스 로직을 처리합니다🎜🎜socket_write
, 그러면 브라우저가 정상적으로 작동합니다. 🎜rrreee🎜 요청에 대한 응답으로 이 예제를 서버에서 실행한 후 브라우저에서 ip:8888
에 액세스하면 다음을 볼 수 있습니다. : 🎜🎜
file_get_content
를 사용하여 요청에 따라 응답할 수 있습니다. 지정된 파일 내용을 브라우저로 반환합니다🎜🎜🎜추천 학습: "🎜PHP 비디오 튜토리얼🎜" 🎜 🎜🎜위 내용은 PHP+Socket 시리즈의 IO 다중화 및 웹서버 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











PHP 8.4는 상당한 양의 기능 중단 및 제거를 통해 몇 가지 새로운 기능, 보안 개선 및 성능 개선을 제공합니다. 이 가이드에서는 Ubuntu, Debian 또는 해당 파생 제품에서 PHP 8.4를 설치하거나 PHP 8.4로 업그레이드하는 방법을 설명합니다.

CakePHP는 PHP용 오픈 소스 프레임워크입니다. 이는 애플리케이션을 훨씬 쉽게 개발, 배포 및 유지 관리할 수 있도록 하기 위한 것입니다. CakePHP는 강력하고 이해하기 쉬운 MVC와 유사한 아키텍처를 기반으로 합니다. 모델, 뷰 및 컨트롤러 gu

CakePHP에 로그인하는 것은 매우 쉬운 작업입니다. 한 가지 기능만 사용하면 됩니다. cronjob과 같은 백그라운드 프로세스에 대해 오류, 예외, 사용자 활동, 사용자가 취한 조치를 기록할 수 있습니다. CakePHP에 데이터를 기록하는 것은 쉽습니다. log() 함수는 다음과 같습니다.

VS Code라고도 알려진 Visual Studio Code는 모든 주요 운영 체제에서 사용할 수 있는 무료 소스 코드 편집기 또는 통합 개발 환경(IDE)입니다. 다양한 프로그래밍 언어에 대한 대규모 확장 모음을 통해 VS Code는

CakePHP는 오픈 소스 MVC 프레임워크입니다. 이를 통해 애플리케이션 개발, 배포 및 유지 관리가 훨씬 쉬워집니다. CakePHP에는 가장 일반적인 작업의 과부하를 줄이기 위한 여러 라이브러리가 있습니다.
