When using PHP to develop socket-based network applications, developers often come into contact with the two functions: socket_accept() and socket_set_block() . Although both functions belong to PHP socket extensions, they are closely related to their use. Understanding their collaborative working mechanism will help us more accurately control the behavior of sockets and improve the reliability and efficiency of network communication.
Before exploring the collaboration of these two functions, let’s first understand their basic functions:
socket_accept(resource $socket): resource|false
This function is used to accept a connection request from the listening socket. If there is no connection request, its behavior depends on the socket's blocking pattern.
socket_set_block(resource $socket): bool
This function sets a socket to blocking mode. In blocking mode, related socket operations (such as socket_accept , socket_read , etc.) will wait until data or connection occurs.
The opposite of socket_set_block() is socket_set_nonblock() , which causes the socket operation to return immediately, regardless of whether there is data or connection.
By default, sockets created by PHP are in blocking mode, which means socket_accept() will block and wait until there is a client connection. That is, if you run the following code:
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 12345);
socket_listen($socket);
$client = socket_accept($socket);
echo "Connection accepted";
Without a client connection, the program will stop at the socket_accept() call until a connection occurs.
Now we introduce socket_set_block() and explicitly set socket to blocking mode (although it is blocking by default, explicit settings can prevent the code from erroring due to previous operations that changed the mode):
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_block($socket); // Explicitly set to blocking mode
socket_bind($socket, '0.0.0.0', 12345);
socket_listen($socket);
$client = socket_accept($socket);
echo "Connection accepted";
At this point, socket_accept() 's behavior does not change: it will still block until there is a client connection.
But if we use socket_set_nonblock() here:
socket_set_nonblock($socket);
Then when socket_accept() is called, if there is no connection request, it will immediately return false , and socket_last_error() can be checked whether it is because of EAGAIN or EWOULDBLOCK , thereby implementing the logic of non-blocking reception of connections.
The collaboration between socket_set_block() and socket_accept() is essentially determined by setting the working mode of socket to determine the blocking behavior of socket_accept() . This setting determines whether the program's control flow is synchronous (blocking) or asynchronous (non-blocking).
For example, when writing high-performance servers, you might use a non-blocking socket and combine socket_select() to listen for multiple connection requests:
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($socket);
socket_bind($socket, '0.0.0.0', 12345);
socket_listen($socket);
$clients = [];
while (true) {
$read = [$socket];
$write = $except = null;
if (socket_select($read, $write, $except, 1) > 0) {
$client = socket_accept($socket);
if ($client !== false) {
$clients[] = $client;
echo "Client connected\n";
}
}
// Handle other logic
}
This method allows you to process multiple sockets simultaneously in a loop without blocking and waiting on socket_accept() .
socket_set_block() determines whether socket blocks work, and socket_accept() is a specific operation affected by this setting. When the socket is blocking mode, socket_accept() waits for the connection; while in non-blocking mode, it returns immediately. The collaborative use of the two allows us to write synchronous or asynchronous network service programs according to actual needs, providing greater flexibility.
Understanding their relationship not only helps write stable socket services, but also lays the foundation for building high-concurrency and low-latency network applications.
For more related examples, please refer to https://gitbox.net/socket-examples .