Bug #79222 [Opn]: unread_bytes do not work

From: Date: Tue, 04 Feb 2020 14:33:00 +0000
Subject: Bug #79222 [Opn]: unread_bytes do not work
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-225359@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=79222&edit=1 ID: 79222 Updated by: nikic@php.net Reported by: skullnobrains at gmail dot com Summary: unread_bytes do not work Status: Open Type: Bug Package: Sockets related Operating System: linux PHP Version: 7.2.27 Block user comment: N Private report: N New Comment: stream_socket_recvfrom() is a raw socket operation, it will perform a direct read from the stream and bypass PHP's internal read buffer. I would expect that if unread_bytes=255 and you did an fread() rather than stream_socket_recvfrom(), then that would return something. Could you test whether it does? > not sure it is a bug. it is quite painful not to be able to determine the number of bytes that > can be read before reading them any more other than with PEEK. That's not how you would typically do it (first time I hear about PEEK...) Normally you set the stream into non-blocking mode and then use stream_select() to determine whether it can be read. In non-blocking mode, fread() will return as much as can be read (which might be an empty string), but will not block the connection. Previous Comments: ------------------------------------------------------------------------ [2020-02-04 14:18:30] skullnobrains at gmail dot com ok, duly noted. it did work reliably at some point though ( and strangely still does in some cases ) this explains why the number of unread bytes would be zero when data just freshly arrived into the network buffer. but that does not really explain why the internal buffer would contain 255 characters when it is actually empty ... ? not sure it is a bug. it is quite painful not to be able to determine the number of bytes that can be read before reading them any more other than with PEEK. thanks for your time best regards ------------------------------------------------------------------------ [2020-02-04 13:39:01] nikic@php.net unread_bytes is the number of bytes stored in PHP's internal read buffer. It does not indicate whether data is available to read or not. That's what stream_select() is for. The documentation has this peculiar note for this value: > Note: You shouldn't use this value in a script. ------------------------------------------------------------------------ [2020-02-04 13:13:06] skullnobrains at gmail dot com Description: ------------ i am directly connecting to a mysql server using stream socket functions. when there is something to read, stream_get_meta_data() reports 0 bytes to read, and 255 when there is nothing to read. i tried multiple 7.x versions and ended up with similar results : 7.2.7 , 7.3 , and a few others Test script: --------------- function my_msg_r($sock){ echo "===== READ =====\n"; var_dump(stream_get_meta_data($sock)['unread_bytes']); $header=stream_socket_recvfrom($sock, 4, STREAM_PEEK); my_od($header); if(4!==strlen($header)) return my_wrn("failed to read a complete packet header"); $len=my_str2int(substr($header,0,3)); if($len===0xffffff)return my_wrn("i do not handle packets longer than 2pow24 yet, sorry"); printf("READ LEN %s 0x%x\n",$len,$len); printf("READ SEQ %u\n",ord($header[3])); /* TODO CHECK THE SEQUENCE NUMBER : THE CALLER SHOULD PASS THE EXPECTED SEQ NUMBER AND WRITE AN OUT OF ORDER ERROR IF SOMETHING GOES WRONG */ /* TODO CHECK WE HAVE ENOUGH UNREAD BYTES OR AT LEAST WHAT LENGTH WE MANAGED TO READ */ //if($n===0xffffff)return fread($sock,$n).my_msg_r($sock); # TODO proper error handling + this is not compatible with async operations return substr(fread($sock,$len+4),4); # TODO proper error handling ! } /* i am not including my_od which merely produces the lines starting with od : one line per character with the increment, decimal ascii code, ascii character, and hex value and have no relation with the bug. this looks like an old 5.6 bug i stumbled upon many years ago and was fixed */ Actual result: -------------- ===== READ ===== int(0) od 0 7 111 od 1 0 0 od 2 0 0 od 3 2  10 READ LEN 7 0x7 READ SEQ 2 CONNECTED AND AUTHENTICATED : Resource id #2 ===== WRITE ===== od 0 15 1111 od 1 0 0 od 2 0 0 od 3 0 0 WRITE LEN=15 WRITE SEQ=0 ===== READ ===== int(0) od 0 1  1 od 1 0 0 od 2 0 0 od 3 1  1 READ LEN 1 0x1 READ SEQ 1 field count=1 ===== READ ===== int(255) ... a this point, i hit ctrl+c because there is and won't be anything to read ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=79222&edit=1

« previous php.bugs (#225359) next »