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