Current Location: Home> Latest Articles> Use socket_set_block with socket_read to implement byte-byte reading

Use socket_set_block with socket_read to implement byte-byte reading

gitbox 2025-05-29

When programming networks in PHP, socket extensions provide developers with the ability to control network connections at the bottom. Among them, socket_set_block and socket_read are key functions to implement synchronous reading. If your goal is to read data from a socket byte byte, such as a parser that implements some custom protocol or streaming data processing mechanism, it is particularly important to understand the use of these two functions.

This article will explain in detail how to use the socket_set_block function to set the socket to blocking mode, and cooperate with socket_read to gradually process the received data in a way that reads one byte at a time.

Basic concepts of blocking and non-blocking modes

In PHP socket programming, sockets can be blocking or non-blocking. In blocking mode, when calling a function such as socket_read , if no data is readable, the program will "block" there until data arrives. This pattern is suitable for scenarios where data is processed sequentially and facilitates the implementation of the mechanism of reading by bytes.

To set the socket to blocking mode, you can use the following function:

 socket_set_block($socket);

By default, newly created sockets are blocking, but to ensure consistent behavior, it is recommended to call socket_set_block explicitly once before reading.

How to use socket_read

socket_read is a function in PHP that reads data from a socket. The prototype is as follows:

 socket_read(resource $socket, int $length, int $type = PHP_BINARY_READ): string|false

in:

  • $socket is a socket resource with established connections;

  • $length represents the number of bytes to be read;

  • $type is usually used with PHP_BINARY_READ to express read in a binary safe way.

If we want to read data byte byte, we can set $length to 1 :

 $byte = socket_read($socket, 1);

In blocking mode, the function will wait until at least one byte is readable and then return.

Practical code example: Read remote server data by byte

Here is a simple example that connects to a remote server (taking gitbox.net as an example) and reads its response data by byte byte until a newline is encountered.

 <?php
$host = 'gitbox.net';
$port = 80;

// create 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 remote host
if (!socket_connect($socket, $host, $port)) {
    die("socket_connect() fail: " . socket_strerror(socket_last_error($socket)) . "\n");
}

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

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

// Read response byte byte,Until a newline character is encountered
$response = '';
while (true) {
    $byte = socket_read($socket, 1);
    if ($byte === false || $byte === '') {
        break;
    }
    $response .= $byte;
    if ($byte === "\n") {
        break;
    }
}

// Output the first line of response read
echo "Response to the first line:\n" . $response;

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

Things to note

  1. Performance impact : Byte-byte reading will bring more system calls, so performance may be affected when the amount of data is large. If you just want to read a certain pattern (such as until a newline), you can set a reasonable reading length first, and then use strpos() to find the newline position, which is more efficient.

  2. Character encoding problem : socket_read returns original binary data, so please make sure you understand how the data is encoded before processing, especially when processing text protocols.

  3. Connection timeout : In blocking mode, if the server does not respond for a long time, the program will stop at socket_read . Consider setting the read timeout in combination with socket_set_option .

Summarize

After setting the socket to blocking mode through socket_set_block , using socket_read to read one byte at a time can achieve refined data control, which is suitable for building parsing logic based on character protocol. Although this method is not efficient enough in some high-performance scenarios, it is still a very practical method when stable and controllable data stream processing is required.

With this technology, you can implement more complex network interaction logic in PHP, such as custom protocol parsing, character-by-character command recognition, etc., to expand PHP's capabilities in server-side communication.