Home >Backend Development >PHP Tutorial >IO multiplexing of PHP+Socket series and implementation of web server

IO multiplexing of PHP+Socket series and implementation of web server

藏色散人
藏色散人forward
2023-02-02 13:43:364043browse

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.

php native socket IO multiplexing and web server implementation

Multiplexing

## Previous article Simple server-client communication is implemented through native sockets, but when multiple clients are connected, the server can only handle the request of the first client and cannot serve subsequent clients

IO multiplexing of PHP+Socket series and implementation of web server

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:

  • Multiple processes, that is, multiple processes are started on the server to monitor

  • IO multiplexing mechanism, which simply implements the use of N clients One network cable simultaneously accesses

and multiplexing is divided into two different models, namely

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.

Syntax

is in In the previous article, we introduced that PHP's native socket has a built-in

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|false
Parameters

  • read

    The socket resource monitored by the server, when it changes (that is, a new message is received or a client is connected or disconnected),

    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

    #Monitor whether there is a client writing data. Passing in

    null means that you don’t care whether there are any write changes.

  • except

    The elements to be excluded in the socket, passing in

    null is "listening" All

  • seconds

    Seconds and microseconds together form the timeout parameter. If

    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

Optimization

In our

last article we simply implemented the socket server-side monitoring connection with the client. Next, we build the basis of the server-side monitoring code. Optimize the code through multiplexing:

<?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 &#39;请求ip: &#39; . $ip . &#39;端口: &#39; . $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

IO multiplexing of PHP+Socket series and implementation of web server

Use socket to implement a simple http server

http protocol specifies the specified data format based on socket, so we only need to

socket_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 == &#39;&#39;) return;

            $output = &#39;<h1>this is php worker</h1>&#39;;
            $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:

IO multiplexing of PHP+Socket series and implementation of web server

At the same time, the server will output the following content:

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

This 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!

Statement:
This article is reproduced at:learnku.com. If there is any infringement, please contact admin@php.cn delete