ID:               28141
 Comment by:       php2 at richardneill dot org
 Reported By:      php at richardneill dot org
 Status:           Feedback
 Bug Type:         Sockets related
 Operating System: Linux
 PHP Version:      5.0.0RC1
 New Comment:

I've still got the same thing happening in PHP5.0.0(final)

I'm having some trouble with your example, so I'm using the attached
instead. It's basically copied from the php-sockets manual, but
slightly modified.

The key point: according to the documentation, when
(socket_read()===false), it means something has gone very wrong, i.e. 
a fatal error. However, in practice, all this means is that the other
side has closed the connection.

I'm running this code as ./testsock.php
and the client is simply: netcat localhost 1111
The problem is that, if netcat is killed with Ctrl-C, then the server
suffers a fatal error. I don't think that it should.

I've tried it under both version  php-cli-4.3.7-4mdk (the current devel
version from Mandrake cooker) and php-5.0.0-cli which I just compiled.
In both cases, the same thing happens.

Regards

Richard

-------------------------------------
#!/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;

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
   echo "socket_create() failed: reason: " . socket_strerror($sock) .
"\n";
}else{
   echo "Created socket $sock\n";
}

if (($ret = socket_bind($sock, $address, $port)) < 0) {
   echo "socket_bind() failed: reason: " . socket_strerror($ret) .
"\n";
}else{
   echo "Bound socket $sock to port $port on address $address\n";
}

if (($ret = socket_listen($sock, 5)) < 0) {
   echo "socket_listen() failed: reason: " . socket_strerror($ret) .
"\n";
}else{
   echo "listening...\n";
}

do {
   if (($msgsock = socket_accept($sock)) < 0) {
       echo "socket_accept() failed: reason: " .
socket_strerror($msgsock) . "\n";
       break;
   }
   /* Send instructions. */
     $msg = "Welcome to the PHP Test Server.\nTo quit, type 'quit'. To
shut down the server type 'shutdown'.\n".
          "To crash this server, quit netcat with Ctrl-C\n";
   socket_write($msgsock, $msg, strlen($msg));

   do {
       $buf = socket_read($msgsock, 2048, PHP_NORMAL_READ);
       if ($buf==''){
          echo "Socket received an  empty string.\n";
       }
       if ($buf ===false){
           echo "socket_read() failed: reason: " .
socket_strerror($ret) . ". This shouldn't happen. Fatal exit.\n";
           break 2;
       }
      /* According to the documentation, testing for socket_read being
false is a sign of a fatal error, whereas an empty string
     is means the remote side has closed the connection. Actually both
"" and false indicate the remote side has closed the connection.
     the socket_strerror isn't very helpful - it says "operation not
permitted"   */

       $buf=trim($buf);         #Trim whitespace.

       if ($buf == 'quit') {
           echo "Quit command received\n";
           break;
       }
       if ($buf == 'shutdown') {
           socket_close($msgsock);
           echo "Shutdown command received\n";
           break 2;
       }
       $talkback = "PHP: You said '$buf'.\n";
       socket_write($msgsock, $talkback, strlen($talkback));
       echo "$buf\n";
   } while (true);

   socket_close($msgsock);
   echo "Closed msgsocket; waiting for another connection\n";
} while (true);

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


Previous Comments:
------------------------------------------------------------------------

[2004-07-18 14:29:51] [EMAIL PROTECTED]

I cannot reproduce the problem with latest PHP5. Can you provide a
*full* reproducing case.
My scripts are :
server:
<?php
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();
$address = '127.0.0.1';
$port = 4322;
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
   echo "socket_create() failed: reason: " . socket_strerror($sock) .
"\n";
}
if (($ret = socket_bind($sock, $address, $port)) < 0) {
   echo "socket_bind() failed: reason: " . socket_strerror($ret) .
"\n";
}
if (($ret = socket_listen($sock, 5)) < 0) {
   echo "socket_listen() failed: reason: " . socket_strerror($ret) .
"\n";
}
do {
   if (($msgsock = socket_accept($sock)) < 0) {
       echo "socket_accept() failed: reason: " .
socket_strerror($msgsock) . "\n";
       break;
   }

   $buffer=socket_read($msgsock,2048,PHP_NORMAL_READ);
   $buffer2=socket_read($msgsock,2048,PHP_NORMAL_READ);

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

   socket_close($msgsock);
} while (true);
socket_close($sock);
?>
client:
<?php
error_reporting(E_ALL);
echo "TCP/IP Connection\n";
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket < 0) {
   echo "socket_create() failed: reason:
".socket_strerror($socket)."\n";
} else {
   echo "OK.\n";
}
echo "Attempting to connect to '127.0.0.1' on port '4322'...";
$result = socket_connect($socket, "127.0.0.1", 4322);
if ($result < 0) {
   echo "socket_connect() failed.\nReason: ($result)
".socket_strerror($result) . "\n";

} else {
   echo "OK.\n";
}
$s = "ALA\n";
socket_write($socket, $s);
echo "Closing socket...";sleep(5);
socket_close($socket);
echo "OK.\n\n";
?>


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

[2004-04-28 04:54:43] php at richardneill dot org

This is still present in RC2

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

[2004-04-25 06:56:24] 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


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


-- 
Edit this bug report at http://bugs.php.net/?id=28141&edit=1

Reply via email to