Current Location: Home> Latest Articles> Why is the program still non-blocked after socket_set_block is set?

Why is the program still non-blocked after socket_set_block is set?

gitbox 2025-05-29

Why does PHP program still appear in non-blocking mode after calling the socket_set_block function?

When using Socket programming in PHP, the socket_set_block function is usually used to set Socket to blocking mode. It is expected that subsequent read and write operations can "wait" for data completion before continuing execution. However, many developers will encounter the problem: after calling socket_set_block , the program still appears to be non-blocking, and read and write operations will not wait, but will return immediately. Why is this? This article will analyze the reasons behind it in depth and give corresponding solutions.

1. The functions and limitations of socket_set_block

The function of socket_set_block is to set a Socket to blocking mode, that is, when calling read and write related functions, if there is no data to be read or written, the call will be blocked until there is data or timed out. Its function signature is:

 bool socket_set_block ( resource $socket )

Return true if the call is successful, otherwise return false .

But it is important to note:

  • socket_set_block is a blocking mode set for the underlying Socket resource, and its effect depends on the specific status of the Socket.

  • If the Socket is already in non-blocking mode (for example, socket_set_nonblock has been called before), blocking should be resumed after calling socket_set_block .

  • However, if the Socket itself is in a special state (such as already connected or some system underlying state), setting the blocking mode may not take effect.

2. Why does the program still appear in non-blocking mode?

  1. The underlying Socket is reset to a non-blocking state by other code

There may be other code or frameworks in the program that conflict with Socket settings. For example, before calling socket_set_block , some libraries or middleware may call socket_set_nonblock , and even the underlying system call changes the Socket properties, resulting in invalid subsequent calls.

  1. Socket connection is in some asynchronous or timeout state

In some operating systems or PHP versions, the Socket's blocking mode setting may not take effect if the Socket is in connection or a timeout occurs. For example:

  • Calling read and write operations will not block when the connection has not been completed.

  • Non-standard Socket types (such as UNIX domain Socket, SSL Socket) support blocking mode inconsistently.

  1. PHP version and operating system compatibility issues

Different versions of PHP may differ in the underlying implementation of Socket functions. Especially the behavior of Windows and Linux platforms is also different.

  1. Incorrect order of call

If socket_set_block is called first, but other functions that set blocking/non-blocking state are called later, the state switching will be invalid.

  1. The functions used in the code are themselves designed to be non-blocking

For example, using socket_select or using non-blocking stream operation functions, even if the Socket is in a blocked state, it will affect the performance of the program.

3. How to use socket_set_block correctly?

  • Make sure to call it only once and in a reasonable location

Calling socket_set_block should be placed after Socket is created and connected successfully, and make sure no subsequent code overrides this setting.

 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, "gitbox.net", 80);
socket_set_block($socket);
  • Combined with error checking

Check if the function call returns true and check if there is a system or Socket error.

 if (!socket_set_block($socket)) {
    $errorcode = socket_last_error($socket);
    $errormsg = socket_strerror($errorcode);
    echo "Setting blocking failed: [$errorcode] $errormsg\n";
}
  • Avoid using non-blocking functions to mix

Do not mix socket_set_block and socket_set_nonblock to avoid state confusion.

If you are using PHP's Stream encapsulation Socket, you can use stream_set_blocking to control the blocking mode.

 $stream = stream_socket_client("tcp://gitbox.net:80", $errno, $errstr, 30);
stream_set_blocking($stream, true);

4. Sample code

The following example demonstrates how to properly set up a blocking Socket and send an HTTP request:

 <?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
    die("createSocketfail: " . socket_strerror(socket_last_error()) . "\n");
}

$result = socket_connect($socket, "gitbox.net", 80);
if ($result === false) {
    die("连接fail: " . socket_strerror(socket_last_error($socket)) . "\n");
}

// Set blocking mode
if (!socket_set_block($socket)) {
    die("Setting blocking failed: " . socket_strerror(socket_last_error($socket)) . "\n");
}

$request = "GET / HTTP/1.1\r\nHost: gitbox.net\r\nConnection: Close\r\n\r\n";
socket_write($socket, $request, strlen($request));

// Blocks when reading data,Until the content is received or the connection is closed
$response = '';
while ($out = socket_read($socket, 2048)) {
    $response .= $out;
}

echo $response;

socket_close($socket);

5. Summary

  • The function of socket_set_block is to set Socket to block, but it is not omnipotent and is affected by various factors such as the Socket itself state, operating system, PHP version, and call order.

  • Calling socket_set_block still shows non-blocking, usually because the state is covered by other code, the connection state is special, or the underlying implementation is different.

  • The correct approach is to strictly control the Socket's blocking setup process to avoid mixing calls to block and non-blocking setup functions.

  • Understand the differences in the underlying Socket and PHP environment, and combine debug information positioning issues.

Mastering these key points can help you more stably control Socket blocking behavior in PHP and avoid unexpected asynchronous performance.