Current Location: Home> Latest Articles> socket_set_block is used with socket_select to block and wait

socket_set_block is used with socket_select to block and wait

gitbox 2025-05-28

The basis of blocking and non-blocking

PHP socket is blocking mode by default, which means that the call will wait until you try to read or write if no data or resources are ready. Instead of blocking mode, the call will return immediately.

We use socket_set_block($socket) to set the socket to blocking mode, and then combine socket_select to wait for the data to arrive.


What is socket_select ?

socket_select is a multiplexed function that can listen for multiple sockets to be read and write or have exception states. Its basic structure is as follows:

 socket_select(array &$read, array &$write, array &$except, int $tv_sec, int $tv_usec)
  • $read : A socket array waiting for "readable" state

  • $write : A socket array waiting for "writable" state

  • $except : socket array waiting for "exception" state

  • $tv_sec / $tv_usec : Waiting timeout in seconds and microseconds


Practical demonstration: Blocking and waiting for client connection

The following is a TCP-based server example that uses socket_set_block with socket_select to block waiting for client connections.

 <?php
// create TCP Sockets
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// Set address reuse
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);

// Bind IP and ports
socket_bind($socket, '0.0.0.0', 8080);

// Start monitoring
socket_listen($socket);

// Set to blocking mode
socket_set_block($socket);

echo "Server started on gitbox.net:8080\n";

// Main loop
while (true) {
    // Initialize the listening array
    $read = [$socket];
    $write = $except = [];

    // use socket_select Blocking and waiting
    $changed_sockets = socket_select($read, $write, $except, 0, 0);

    if ($changed_sockets === false) {
        echo "socket_select failed: " . socket_strerror(socket_last_error()) . "\n";
        break;
    }

    // If the main socket Readable,Indicates that there is a new connection request
    if (in_array($socket, $read)) {
        $client = socket_accept($socket);
        if ($client !== false) {
            echo "New client connected\n";

            // Send a message to the client
            $msg = "Welcome to gitbox.net server!\n";
            socket_write($client, $msg, strlen($msg));

            // Close client connection
            socket_close($client);
        }
    }
}

// Close the main socket
socket_close($socket);
?>

Key points description

  1. Blocking behavior : Because socket_set_block is used, socket_accept will block and wait when there is no connection request. Combined with socket_select , thread idling can be avoided.

  2. Flexible timeout control : The socket_select timeout parameter can be used to control blocking time, which is very useful in some services that require polling or heartbeat mechanisms.

  3. Multi-client support : by adding multiple sockets to the $read array, socket_select can effectively support multiple connections, making it easier to build a high-concurrency server.