ID: 28141 Updated by: [EMAIL PROTECTED] Reported By: php at richardneill dot org -Status: Assigned +Status: Bogus Bug Type: Sockets related Operating System: Linux PHP Version: 4CVS, 5CVS (2005-02-14) Assigned To: andrey New Comment:
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"; ?> Previous Comments: ------------------------------------------------------------------------ [2004-07-28 21:04:13] [EMAIL PROTECTED] Assigning to myself (to get notification if i forget), changing the version. ------------------------------------------------------------------------ [2004-07-26 10:37:34] php at hristov dot com I will take a look later today or these days. But for now, the code in the function is : if (type == PHP_NORMAL_READ) { retval = php_read(php_sock->bsd_socket, tmpbuf, length, 0); } else { retval = recv(php_sock->bsd_socket, tmpbuf, length, 0); } if (retval == -1) { PHP_SOCKET_ERROR(php_sock, "unable to read from socket", errno); efree(tmpbuf); RETURN_FALSE; } ------------------------------------------------------------------------ [2004-07-18 17:13:56] php2 at richardneill dot org 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"; ?> ------------------------------------------------------------------------ [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-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