PHP socket_read() only gets the first byte of the stream

PHP socket_read() only gets the first byte of the stream … here is a solution to the problem.

PHP socket_read() only gets the first byte of the stream

When using socket_read() in linux, I encountered a very strange behavior.

I’m using a socket_read with a buffer limit of 2048.

While on my Windows system it gets the

entire response, on my Linux server it only gets the first byte of the response.

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!socket_connect($sock, 'my-server.dyndns.org', 8888)) {
   die('no connect');
}

$req = 'request';
socket_write($sock, $req);

if (false !== ($buf = socket_read($sock, 2048)) {
    echo $buf;  This only contains the first byte of the response.
}

socket_close($sock);

If I call socket_read() again, it gets the rest of the string:

// This works: 

while((false !== ($buf = socket_read($sock, 2048)))) {
    echo "Read ".strlen($buf)." bytes from socket_read().\n";
    if ($buf == "") break;
    $b .= $buf;
    sleep(1);
}

/* Output: 
 *
 * Read 1 bytes from socket_read().
 * Read 307 bytes from socket_read().
 * Read 0 bytes from socket_read().
 * Done.
 */ 

If I wait 2 seconds before calling socket_read(), I also get a valid response:

// This also works:

sleep(2);
if (false !== ($buf = socket_read($sock, 2048)) {
    echo $buf;  all 308 bytes are read correctly.
}

Shouldn’t socket_read() wait for the buffer to become full, or for the string to end?

What am I doing wrong?

Solution

As we all know, the networking stack on

Linux is better (and faster) than the networking stack on Windows (this is subjective, let’s just say: it behaves differently). On the other hand, this means that your code also needs to handle the differences.

Sockets are not real-time, but asynchronous. So, if you write something to a socket, you can’t expect that you can already read it. You need to give the remote daemon some time to actually respond to your writes.

You can only read it if the remote end has actually written something to your socket and the network has transmitted that data.

Related Problems and Solutions