Edit report at http://bugs.php.net/bug.php?id=52848&edit=1

 ID:                 52848
 Updated by:         [email protected]
 Reported by:        php dot net at phrozenbyte dot de
 Summary:            Processing out-of-band data doesn't work
 Status:             To be documented
 Type:               Bug
 Package:            Streams related
 Operating System:   Ubuntu 10.04 Lucid Lynx
 PHP Version:        5.3.3
 Block user comment: N

 New Comment:

There's still no bug. Here's a portion of the strace on the server:



socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3

setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0

bind(3, {sa_family=AF_INET, sin_port=htons(1234),
sin_addr=inet_addr("127.0.0.1")}, 16) = 0

listen(3, 32)                           = 0

poll([{fd=3, events=POLLIN|POLLERR|POLLHUP}], 1, 25000) = 1 ([{fd=3,
revents=POLLIN}])

accept(3, {sa_family=AF_INET, sin_port=htons(42533),
sin_addr=inet_addr("127.0.0.1")}, [16]) = 4

select(5, [3 4], [], [4], NULL)         = 2 (in [4]], except [4])



So you call see that the call to select() actually returned the socket
handle in both fd_set structures, as PHP reported.



The reason for returning the socket handle in readfs is that the
connection was closed on the client side. If you don't close the
connection, you get your expected result.



Keep the same code on the server and use this for the client:



<?php

$socket = stream_socket_client('tcp://127.0.0.1:1234');

stream_socket_sendto($socket, 'a', STREAM_OOB);

sleep(10);

fclose($socket);



You now see:



number of $read sockets: 0

number of $except sockets: 1


Previous Comments:
------------------------------------------------------------------------
[2010-09-16 04:43:44] php dot net at phrozenbyte dot de

Yes, I understand that.

The issue is in a more special case: When the client sends a single byte
(!) with OOB flag, the server will receive 2 recv calls - the first one
including the single byte with OOB flag and the second one is empty
which results in feof() = true.

That means: Even when you send only a single byte with OOB flag, in
which case you can't read non-OOB-data, stream_select() triggers that
you can read non-OOB-data. And this is a issue with php I think.





Client:

---------------

<?php

$socket = stream_socket_client('tcp://127.0.0.1:1234');

stream_socket_sendto($socket, 'a', STREAM_OOB);

fclose($socket);

?>



Server:

---------------

<?php

$server = stream_socket_server('tcp://127.0.0.1:1234');

$socket = stream_socket_accept($server);

$read = array($server, $socket); $write = array(); $except =
array($socket);

stream_select($read, $write, $except, null);

echo 'number of $read sockets: '.count($read)."\n";

echo 'number of $except sockets: '.count($except)."\n";

?>



Expected result:

---------------

number of $read sockets: 0

number of $except sockets: 1



Actual result:

---------------

number of $read sockets: 1

number of $except sockets: 1

------------------------------------------------------------------------
[2010-09-16 02:06:58] [email protected]

few additional comments



on Linux/Solaris socket implementations, when you send with MSG_OOB
flags set, only the last byte is recvd. the subsequent recv call will
flush out the rest of the bytes.



for example, in your example,if you edit it like below you will notice
this more clearly:



client script



<?php

$socket = stream_socket_client('tcp://127.0.0.1:1234');

stream_socket_sendto($socket, '123456789', STREAM_OOB);

fclose($socket);

?>



server (with 2 recv calls even though client is sending only one send
call.)

<?php

$server = stream_socket_server('tcp://127.0.0.1:1234');

stream_set_timeout($server, 180);

$socket = stream_socket_accept($server);

echo "Data: '".stream_socket_recvfrom($socket, 100, STREAM_OOB)."'\n";

echo "Data: '".stream_socket_recvfrom($socket, 100)."'\n";

?>



Hope this clarifies

I don't think this is an issue with PHP.

------------------------------------------------------------------------
[2010-09-15 22:17:16] php dot net at phrozenbyte dot de

When you're sending data out-of-band (one or more bytes make no
difference) and the client socket is in $read and $except of
stream_select() the socket will be available every time in both arrays.

------------------------------------------------------------------------
[2010-09-15 20:41:18] php dot net at phrozenbyte dot de

Ok, thanks. As cataphract at php dot net mentioned first there are
situations on which even that single byte isn't shown. I'm not able to
reproduce the bug, the only possibility is to repeat running my test
server and client. After some trys the script will result in

OOB-Data 1/2: ''

OOB-Data 2/2: ''

Data 1/2: '12345678'

Data 2/2: ''

------------------------------------------------------------------------
[2010-09-15 16:15:20] [email protected]

It should be documented in stream_socket_sendto and
stream_socket_recvfrom, that OOB data can be only one byte long.

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    http://bugs.php.net/bug.php?id=52848


-- 
Edit this bug report at http://bugs.php.net/bug.php?id=52848&edit=1

Reply via email to