Bug->Req #64803 [Opn->Dup]: async stream_socket_client return
| From: | bukka@php.net | Date: | Mon, 08 May 2023 16:59:31 +0000 |
| Subject: | Bug->Req #64803 [Opn->Dup]: async stream_socket_client return | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-244402@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=64803&edit=1
ID: 64803
Updated by: bukka@php.net
Reported by: rdlowrey at gmail dot com
Summary: async stream_socket_client return
-Status: Open
+Status: Duplicate
-Type: Bug
+Type: Feature/Change Request
Package: Streams related
Operating System: Fedora 17
PHP Version: 5.4.15
-Assigned To:
+Assigned To: bukka
Block user comment: N
Private report: N
New Comment:
I have done some debugging of this and the way how stream_select works is expected because it
matches the C behavior. The connect man page even specifies that it is necessary to use select /
poll after the async connect (connect on non blocking socket). Basically when the async connect is
done, then it might return EINPROGRESS and if that happens it is marked as successful and the user
should use select to wait for finishing of the operation. The problem is that there is no way to get
socket error info. It means calling
getsockopt(fd, SOL_SOCKET, SO_ERROR, ...)
It would need some function like stream_socket_last_error(). This is actually already requested in
https://bugs.php.net/bug.php?id=34380 and after
just reading comments, it even specifies this issue so marking this as a duplicate.
Previous Comments:
------------------------------------------------------------------------
[2013-05-09 18:27:26] rdlowrey at gmail dot com
Description:
------------
Normally when creating a client socket connection asynchronously you have to wait
until the socket stream can be selected as writable to determine whether or not
the connection succeeded. However, when connecting to a nonexistent server on the
loopback address there is no way to differentiate between a failed connection and
a successful connection using the STREAM_CLIENT_ASYNC_CONNECT flag.
The example code connects to a nonexistent server so it should always fail. PHP
reports the connection as having succeeded and it's not until you actually
attempt to read or write to the socket stream that you can get an accurate
feof() return value.
Test script:
---------------
<?php
$uri = '127.0.0.1:9000'; // <-- NOTHING LISTENING ON THIS PORT!
$flags = STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT;
$socket = stream_socket_client($uri, $errNo, $errStr, $timeout=42, $flags);
usleep(50000); // just in case
var_dump($socket); // resource(5) of type (stream)
$w = [$socket];
$r = $e = [];
if (stream_select($r, $w, $e, 0, 0)) {
$selectedSock = current($w);
var_dump($selectedSock); // resource(5) of type (stream) ... says it's writable, BUT IT
CAN'T POSSIBLY BE WRITABLE
}
$r = [$socket];
$w = $e = [];
if (stream_select($r, $w, $e, 0, 0)) {
$selectedSock = current($r);
var_dump($selectedSock); // resource(5) of type (stream) ... says it's readable, let's
check for EOF
}
usleep(50000); // just in case
$isFeof = feof($selectedSock);
var_dump($isFeof); // bool(false) ... not EOF ... WTF?
var_dump(fread($selectedSock, 8192)); // string(0) ""
var_dump(feof($selectedSock)); // bool(TRUE) -- Now we know the truth!
Expected result:
----------------
feof($socket) on an asynchronously connected socket stream should return TRUE if
the connection attempt failed once the socket becomes "writable."
Actual result:
--------------
It's not possible to determine if the connection attempt failed without first
attempting to read/write to/from the socket stream.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=64803&edit=1