PHP socket-some fragmentary details

  epoll, libevent, Non-blocking, php, socket

Original text:https://t.ti-node.com/thread/ …

The front can be said to have got a series of php socket and a lot of multi-process content. The knowledge is simple, the code is rough and the style is crude. Generally speaking, there are still some details missing. Today, I would like to add some missing details.

  1. Some aspiring young people may have recently used the Workerman source code and expressed doubts about the large lump of stream_select (), stream_socket_server (). What is the difference between this tool and socket_create, SOCKET _ socket_set_nonblock ()? In fact, php official manual also mentioned a mouth, socket system function is based on BSD Socket that a set of things, is almost a simple package of those things directly copy to use, copy to even the name and c language control socket function exactly the same, so socket system function is a relatively Low-Level (low-level here refers to the level of hierarchy in software engineering) socket control mode, can give you the maximum degree of freedom and fineness of operation socket. In php, the socket system itself is embodied as a php extension. You can check whether there is a socket through php -m, which means that some php environments may not have this extension installed. At this time, you cannot use socket system functions. But stream is different. This product is built in php. In addition to handling socket network IO, it can also control the opening, writing and reading of common files. stream abstracts these inputs and outputs into streams and treats everything through streams. Some people may ask about the difference in performance between the two, but I have not tested it, so I dare not say anything rashly. However, if deduced from normal logic, there should not be too big a difference.
  2. We must clearly distinguish between monitoring socket and connection socket. Our server monitors socket, and then accept a client connection called connection socket.
  3. As for “asynchronous non-blocking”, where exactly are these five words reflected? Swoole i won’t say, i only read a small part of the source code, i will say Workerman. It said on github: “worker man is an asynchronous event driver php framework with high performance for easy building fast.” When I saw the word asynchronous in it, what hit me in the face was that I didn’t see the word non-block, but it’s ok, face or something is not important, what matters is where non-block and asynchrony are reflected in the code one after another in my article. Come on, look at the code.

    Before looking at the code, you should understand the difference between asynchronous and non-blocking, because the two look a little similar in performance results. If you don’t understand, you must understand through thisA Preliminary Study of PHP socket-Some Boring Theories about IO.

<?php
// 创建一个监听socket,这个一个阻塞IO的socket
$listen = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );
socket_bind( $listen, '0.0.0.0', 9999 );
socket_listen( $listen );
while( true ){
     // socket_accept也是阻塞的,虽然有while,但是由于accpet是阻塞的,所以这段代码不会进入无限死循环中
     $connect = socket_accept( $listen );
     if( $connect ){
       echo "有新的客户端".PHP_EOL;
     } else {
       echo "客户端连接失败".PHP_EOL;
     }
}

Save and run the above code, and then telnet can be used to connect it. However, there are two blocks in this code, the most important is that listening socket is blocked. So, what would it be like to listen to socket without blocking?

<?php
// 创建一个监听socket,将其设置为非阻塞
$listen = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );
socket_bind( $listen, '0.0.0.0', 9999 );
socket_listen( $listen );
// ⚠️⚠️⚠️⚠️⚠️⚠️ 这里设置非阻塞!
socket_set_nonblock( $listen );
while( true ){
     $connect = socket_accept( $listen );
     if( $connect ){
       echo "有新的客户端".PHP_EOL;
     } else {
       echo "客户端连接失败".PHP_EOL;
     }
}

Save and run the code and tell me:

Come on, let’s analyze why this phenomenon occurs. Because the listening socket is set to non-blocking, we know that non-blocking means that the program returns immediately, and then comes back to ask after a while. An example is “while waiting for steamed bread, look at the microblog and look up to ask if steamed bread is ready?” Then look at WeChat, look up and ask if steamed bread is ready? Then look at v2ex, look up and ask if steamed bread is ready? . . . . . 。” , so that you can understand? Since there is no client connected, the feedback after asking socket_accept every time is “no connection”, so I went directly to the branch of “client connection failure” and kept on doing so. At this time, if you use htop or top command to check the server CPU, it should be 100%, which is a great disadvantage of non-blocking.

What about asynchrony? Where is asynchrony reflected? When we said asynchronous, you went to ah mui’s place to buy steamed bread. ah mui told you that “the steamed bread is not ready yet, you can do something else. I’ll call you when it is ready.” then you concentrated on playing the game until the phone rang and you went to get the steamed bread. Workerman’s asynchrony is more embodied in the processing flow of a complete request than in the serious definition of asynchrony. if you don’t understand it, it may be normal and slowly understood. Finally, I add: epoll is synchronous, not asynchronous.