Home > Article > Backend Development > IO multiplexing of PHP+Socket series and implementation of web server
This article brings you relevant knowledge about php socket, which mainly introduces IO multiplexing and how php socket implements web server? Friends who are interested can take a look below. I hope it will be helpful to everyone.
Multiplexing
The reason for this situation is that the IO model is blocking and can only be accessed by one client at the same time. There are two main solutions to solve this problem:
select and
epoll, common In the software,
Apache uses the
select model, and
nginx uses the
epoll model. The
select model is built into php, and the corresponding function is
socket_select. Multiplexing is the basis for implementing the http server.
socket_select function that implements the
select model. Its syntax is as follows:
socket_select( array &$read, array &$write, array &$except, int $seconds [, int $microseconds = 0]): int|falseParameters
read
The socket_select function will return (otherwise it will continue to block), and at the same time modify the variable to the socket resource list of the current event (received message or client connection or disconnection), and continue to execute downwards.
write
null means that you don’t care whether there are any write changes.
except
null is "listening" All
seconds
null is passed in, it will block, and if it is 0, it will be non-blocking. If it is >0, it will be the maximum blocking time
microseconds
<?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; } } }In this example, the
socket_select function will block the current process. When the
$tmp_sockets socket resource in the array has new When the client connects or disconnects or receives a new message, it will modify the
$tmp_sockets array to the currently active socket resource, and then process the business logic by traversing the array
Use socket to implement a simple http server
http protocol specifies the specified data format based on socket, so we only need tosocket_write When sending data according to the format, the browser can respond to the request normally
<?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>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); } } }Run this example on the server, and then access
ip:8888 in the browser, you can see the following:
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.0This content is the original data requested by the user, which can parse this data and respond according to the request, such as using
file_get_content Read the content of the specified file and return it to the browser
Recommended learning: "PHP Video Tutorial"
#The above is the detailed content of IO multiplexing of PHP+Socket series and implementation of web server. For more information, please follow other related articles on the PHP Chinese website!