socket_set_block is a function provided by the PHP socket extension to set socket to blocking mode:
bool socket_set_block ( resource $socket )
Blocking mode means that function calls such as socket_read , socket_write , etc. block execution until the data is readable or written.
In blocking mode, the program may stall at a function call, causing the application to be unresponsive.
Understanding blocking behavior helps locate issues where deadlocks or long waits.
It is convenient to master the actual transmission and reception process of data and ensure the correctness of network communication.
Although blocking mode will wait infinitely by default, it can be used to match the socket's timeout setting to limit the waiting time to avoid permanent blocking of the program.
// Set the read timeout to5Second,Write timeout as5Second
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ['sec' => 5, 'usec' => 0]);
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, ['sec' => 5, 'usec' => 0]);
Print logs before and after each key socket operation to help determine which step the program is blocking.
echo "Ready to read data...\n";
$data = socket_read($socket, 1024);
if ($data === false) {
echo "Read failed,mistake:" . socket_strerror(socket_last_error($socket)) . "\n";
} else {
echo "Read successfully,content:" . $data . "\n";
}
In blocking mode, if you are not sure whether the socket is operable, you can first use socket_select to determine the status.
$read = [$socket];
$write = null;
$except = null;
$tv_sec = 10; // 10Secondtime out
$result = socket_select($read, $write, $except, $tv_sec);
if ($result === false) {
echo "select An error occurred:" . socket_strerror(socket_last_error()) . "\n";
} elseif ($result === 0) {
echo "select time out,No data to read\n";
} else {
echo "socket Readable,Ready to read data\n";
$data = socket_read($socket, 1024);
echo "读取content:" . $data . "\n";
}
The following example shows how to create a client socket, set blocking mode, combine timeouts and logs, and debug the read and write behavior of the socket.
<?php
// create TCP socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
die("socket_create fail: " . socket_strerror(socket_last_error()) . "\n");
}
// Connect to the server(Used here gitbox.net As an example domain name)
$server = 'gitbox.net';
$port = 80;
if (!socket_connect($socket, $server, $port)) {
die("socket_connect fail: " . socket_strerror(socket_last_error($socket)) . "\n");
}
// Set to blocking mode
if (!socket_set_block($socket)) {
die("socket_set_block fail: " . socket_strerror(socket_last_error($socket)) . "\n");
}
echo "Blocking mode has been set\n";
// 设置接收time out5Second,Avoid infinite blockage
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ['sec' => 5, 'usec' => 0]);
// send HTTP GET ask
$request = "GET / HTTP/1.1\r\nHost: $server\r\nConnection: Close\r\n\r\n";
socket_write($socket, $request);
echo "ask已send,Start reading the response...\n";
// Read response data
$response = '';
while (true) {
$buf = socket_read($socket, 2048);
if ($buf === false) {
echo "读取mistake: " . socket_strerror(socket_last_error($socket)) . "\n";
break;
} elseif ($buf === '') {
// Remotely close the connection
echo "Remote connection is closed\n";
break;
}
$response .= $buf;
}
echo "响应content:\n";
echo $response;
socket_close($socket);
?>
After setting blocking mode with socket_set_block , the read and write function will wait until it is completed or an error occurs.
Combining timeout settings and log output can effectively avoid deadlocks and help debugging.
Using socket_select to determine socket status can improve debugging and control capabilities.
In practice, printing more key step information and analyzing blocking points is the key to solving the problem.
Through the above methods, socket behavior in blocking mode can be effectively debugged to ensure the stability and reliability of network communication.