Bug->Doc #62394 [Opn->Ver]: socket_read non-blocking resets timeout with no data read
| From: | cmb@php.net | Date: | Tue, 06 Apr 2021 12:30:54 +0000 |
| Subject: | Bug->Doc #62394 [Opn->Ver]: socket_read non-blocking resets timeout with no data read | ||
| References: | 1 | Groups: | php.doc.bugs |
| Request: | Send a blank email to doc-bugs+get-18688@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=62394&edit=1
ID: 62394
Updated by: cmb@php.net
Reported by: sysfly at gmail dot com
Summary: socket_read non-blocking resets timeout with no data
read
-Status: Open
+Status: Verified
-Type: Bug
+Type: Documentation Problem
Package: Sockets related
Operating System: Windows
PHP Version: 5.3.14
Block user comment: N
Private report: N
New Comment:
> Maybe there's a distinction to be made between fatal and
> nonfatal socket errors.
There is already an distinction: EAGAIN and EWOULDBLOCK are not
reported via the general PHP error handling mechanism. If you
remove the silence operator from the socket_read() call, there are
no additional warnings for these conditions. And of course, you
can add special handling for EAGAIN/EWOULDBLOCK (it's a bit
unfortunate that the error numbers are different for Windows and
other systems, but this is not a big deal either).
The timeout also behaves as expected, since recv(2) returns before
the timeout expires.
Note that ext/sockets is a low-level interface to BSD sockets, so
changing this long standing behavior just "because it is
inconvenient" is not an option. We should, however, improve the
docs to mention this peculiarity.
If anybody feels strongly that the behavior should be changed,
please pursue the RFC process[1].
[1] <https://wiki.php.net/rfc/howto>
Previous Comments:
------------------------------------------------------------------------
[2012-06-22 10:31:56] sysfly at gmail dot com
Description:
------------
If you call socket_read and it throws an error such as socket error 10035 then the
connection will never timeout even if the remote side disconnects. Socket error
10035 is thrown if data is not ready to be read (hasn't been sent) yet and is not
really indicative of a disconnect or other fatal error.
Maybe there's a distinction to be made between fatal and nonfatal socket errors.
Possibly have it return an empty string instead of throwing a nonfatal error?
There is no data to read so that seems to be the more appropriate course of
action.
Test script:
---------------
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$connected = socket_connect($socket, '127.0.0.1', 1337); // some server that never sends
you data. connection must be accepted though, or else this throws an error.
socket_set_nonblock($socket);
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 1, 'usec'
=> 0)); // set timeout to something fast, a second.
while (($read = @socket_read($socket, 1)) === false)
{
// socket_read throwing an error doesn't mean the connection has failed and the server is gone
// in context, it just means the server hasn't sent any data yet. [in testing, it never will.]
if (socket_last_error($socket) != 10035)
break; // an error that probably means we disconnected has been thrown!
}
echo('yay we did it! '.socket_last_error($socket));
Expected result:
----------------
yay we did it! (some FATAL error code)
Actual result:
--------------
infinite nothingness unless set_time_limit is set, in which case the typical time
limit exceeded error interrupts the script.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=62394&edit=1