Bug->Req #64803 [Opn->Dup]: async stream_socket_client return

From: 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

« previous php.bugs (#244402) next »