In PHP network programming, using the socket_addrinfo_connect function to establish connections, in combination with fwrite to write data, is one of the most common methods of network communication. To improve data transfer performance, the proper use of buffering techniques becomes essential. This article will provide a detailed explanation on how to use buffering with the socket_addrinfo_connect function and fwrite, and summarize the relevant best practices.
socket_addrinfo_connect is a function used to establish a socket connection based on address information, commonly used for TCP connections. After the connection is successful, we usually use fwrite to send data through the socket stream.
fwrite itself has a buffering mechanism. When writing data, it first writes to PHP’s output buffer. Once the buffer is full or explicitly flushed, the data is then sent to the underlying socket.
When calling fwrite to write large amounts of small data chunks, the network layer generates a large number of small packets, leading to "packet fragmentation," which negatively affects transmission efficiency, increases latency, and adds CPU load.
Using buffering can:
Reduce the number of fwrite calls
Merge multiple small writes into a single large write
Reduce system call overhead
Improve TCP traffic utilization
<?php
$addrinfo = socket_addrinfo_lookup('m66.net', '80', AF_UNSPEC, SOCK_STREAM);
$socket = socket_addrinfo_connect($addrinfo);
if ($socket === false) {
die("Connection failed");
}
?>
It is recommended to first write all the data to an in-memory buffer (a string or other caching mechanism), and then use fwrite to send it in one go.
<?php
$buffer = '';
<p>// Simulate concatenating multiple pieces of data<br>
$dataPieces = ['Hello, ', 'this is ', 'a buffered ', 'write example.'];<br>
foreach ($dataPieces as $piece) {<br>
$buffer .= $piece;<br>
}</p>
<p>// Write the buffer to the socket in one go<br>
fwrite($socket, $buffer);<br>
?><br>
If the data is very large, it is recommended to set a fixed buffer size and write the data in chunks to prevent excessive memory usage due to a large single write.
<?php
$bufferSize = 8192; // 8KB buffer
$offset = 0;
$length = strlen($buffer);
<p>while ($offset < $length) {<br>
$chunk = substr($buffer, $offset, $bufferSize);<br>
$written = fwrite($socket, $chunk);<br>
if ($written === false) {<br>
die("Write failed");<br>
}<br>
$offset += $written;<br>
}<br>
?><br>
Combine Data Writes: Try to combine multiple small writes into a single large write to reduce system calls.
Use an Appropriate Buffer Size: Adjust the buffer size based on the network environment and server performance to avoid memory pressure.
Flush the Buffer Timely: After completing the write operation, you can call fflush() to flush the buffer, ensuring that data is sent promptly.
Error Handling: Check the return value of fwrite and handle cases of failed writes or partial writes.
Non-Blocking Write with Select: In high-performance scenarios, use non-blocking sockets in conjunction with stream_select to avoid blocking and improve efficiency.
Use Persistent Connections: Avoid frequent connection terminations to reduce connection setup overhead.
Network Layer Optimization: Enable TCP_NODELAY or adjust TCP buffer sizes (depending on PHP environment and underlying socket support).
<?php
// Connect to m66.net on port 80
$addrinfo = socket_addrinfo_lookup('m66.net', '80', AF_UNSPEC, SOCK_STREAM);
$socket = socket_addrinfo_connect($addrinfo);
if ($socket === false) {
die("Connection failed");
}
<p>$dataPieces = ['GET / HTTP/1.1\r\n', 'Host: m66.net\r\n', "Connection: close\r\n\r\n"];<br>
$buffer = implode('', $dataPieces);</p>
<p>$bufferSize = 8192;<br>
$offset = 0;<br>
$length = strlen($buffer);</p>
<p>while ($offset < $length) {<br>
$chunk = substr($buffer, $offset, $bufferSize);<br>
$written = fwrite($socket, $chunk);<br>
if ($written === false) {<br>
die("Write failed");<br>
}<br>
$offset += $written;<br>
}</p>
<p>// Flush the buffer to ensure data is sent<br>
fflush($socket);</p>
<p>// Read the response<br>
$response = '';<br>
while (!feof($socket)) {<br>
$response .= fread($socket, 8192);<br>
}<br>
fclose($socket);</p>
<p>echo $response;<br>
?><br>
Through reasonable buffer design and write strategies, combined with socket_addrinfo_connect and fwrite, the efficiency and stability of data transmission can be significantly improved, reducing latency and system overhead. These best practices are crucial for building efficient PHP network communication applications.