php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #28141 socket_read return type: false vs "", when PHP_NORMAL_READ
Submitted: 2004-04-25 06:56 UTC Modified: 2005-02-15 13:09 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: php at richardneill dot org Assigned: andrey (profile)
Status: Closed Package: Documentation problem
PHP Version: 4CVS, 5CVS (2005-02-14) OS: Linux
Private report: No CVE-ID: None
 [2004-04-25 06:56 UTC] php at richardneill dot org
Description:
------------
According to the documentation, socket_read() can return:

1)A string - normal data
2)An empty string "" - the other end closed the connection
3)false - something went wrong.

But it seems to be returning false on connection close.

Reproduce code:
---------------
$buffer=socket_read($socket,2048,PHP_NORMAL_READ);	

if ($buffer===false){
     echo "Error: socket_read() failed: reason: ".socket_strerror(socket_last_error())." \n";
     exit (1);
}elseif ($buffer==''){
    echo "Socket $socket returned an empty string. Closing connection\n";
	socket_close($socket);
}else{
    echo "Received data".trim($buffer)."\n";
}

Expected result:
----------------
I'm using netcat as a client, and then killing the netcat process with Ctrl-C to simulate remote host disconnecting.

I expect to see the socket close.

Actual result:
--------------
Actually, the php script exits, because socket_read returns 
false instead of "".

This may be a bug in the documentation for socket_read, rather than in its behaviour. 

Thanks for your help - Richard

Patches

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-02-14 09:10 UTC] sniper@php.net
There is no bug to fix here. You're actually getting "Connection reset by peer" (ECONNRESET) and that makes recv() to return -1 -> PHP socket_read() returns an error and FALSE.

Here's simplified WORKING script:

#!/usr/local/bin/php
<?php
error_reporting(E_ALL);

/* Allow the script to hang around waiting for connections. */
set_time_limit(0);

/* Turn on implicit output flushing so we see what we're getting as it
comes in. */
ob_implicit_flush();

$address = '127.0.0.1';
$port = 1111;

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock, $address, $port);
socket_listen($sock, 5);

do {
   $msgsock = socket_accept($sock);

   do {
       $buf = socket_read($msgsock, 2048, PHP_NORMAL_READ);
       var_dump($buf);
   } while ($buf !== FALSE && $buf !== '');

   echo socket_strerror(socket_last_error($msgsock));
   socket_close($msgsock);

   echo "Closed msgsocket; waiting for another connection\n";

} while (true);

socket_close($sock);
echo "Closed main socket, exiting\n";

?>

 [2005-02-14 17:30 UTC] php at richardneill dot org
Thanks. That makes sense. However, it still leaves a few problems, essentially with wrong documentation.

-------------------
1)The documentation for socket_read 
http://uk.php.net/manual/en/function.socket-read.php
claims:

"Note:  socket_read() may return a zero length string ("") indicating the end of communication (i.e. the remote end point has closed the connection)."

which is obviously not true.
---------------------

2)Example 1 on the sockets page
http://uk.php.net/manual/en/ref.sockets.php
also supports the interpretation that 
False => error; null => connection closed

       if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
           echo "socket_read() failed: reason: " . socket_strerror($ret) . "\n";
           break 2;
       }
       if (!$buf = trim($buf)) {
           continue;
       }


----------------------

3)How is one to determine the difference between 
 i)the other side closing the connection normally
and 
 ii)something going very wrong with the function?

According to the documentation, 

   ""   => (i)
  false =>  (ii)

In fact, it seems that 

  false  => (i) or (ii), with no way to tell
  ""     =>  never actually happens
  

Thanks for your help,

Richard
 [2005-02-14 22:20 UTC] sniper@php.net
From recv() manpage:

"Upon successful completion, recv() shall return the length of the message in bytes. If no messages are available to be received and the peer has performed an orderly shutdown, recv() shall return 0. Otherwise, -1 shall be returned and errno set to indicate the error."


 [2005-02-14 22:23 UTC] sniper@php.net
Forgot this part from that: recv() function is what socket_read() uses internally.

 [2005-02-15 13:09 UTC] nlopess@php.net
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.

Thank you for the report, and for helping us make our documentation better.


 [2020-02-07 06:11 UTC] phpdocbot@php.net
Automatic comment on behalf of nlopess
Revision: http://git.php.net/?p=doc/en.git;a=commit;h=26144c6e9bf3109e49acd92e0d0e85b4ea8eda09
Log: fix #28141: return values - false/empty string
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Aug 14 01:01:28 2024 UTC