On Wed, Aug 26, 2009 at 5:36 PM, Philip Thompson <philthath...@gmail.com>wrote:

> On Aug 26, 2009, at 2:47 PM, Bob McConnell wrote:
>
>  From: Philip Thompson
>>
>>> On Aug 26, 2009, at 11:56 AM, Bob McConnell wrote:
>>>
>>>> From: Philip Thompson
>>>>
>>>>>
>>>>> During a socket read, why would all the requested number of bytes
>>>>>
>>>> not
>>
>>> get sent? For example, I request 1000 bytes:
>>>>>
>>>>> <?php
>>>>> $data = @socket_read ($socket, 2048, PHP_BINARY_READ);
>>>>> ?>
>>>>>
>>>>> This is actually in a loop, so I can get all the data if split up.
>>>>> So,
>>>>> for example, here's how the data split up in 3 iterations (for 1000
>>>>> bytes):
>>>>>
>>>>> 650 bytes
>>>>> 200 bytes
>>>>> 150 bytes
>>>>>
>>>>> But if I can accept up to 2048 bytes per socket read, why would it
>>>>> not
>>>>> pull all 1000 bytes initially in 1 step? Any thoughts on this would
>>>>>
>>>>
>>  be
>>>>> greatly appreciated!
>>>>>
>>>>
>>>> Because that's the way TCP/IP works, by design. TCP is a stream
>>>> protocol. It guarantees all of the bytes written to one end of the
>>>> pipe
>>>> will come out the other end in the same order, but not necessarily in
>>>> the same groupings. There are a number of buffers along the way that
>>>> might split them up, as well as limits on packet sizes in the various
>>>> networks it passed through. So you get what is available in the last
>>>> buffer when a timer expires, no more, and no less.
>>>>
>>>> If you have serialized data that needs to be grouped in specific
>>>> blocks,
>>>> your application will need to keep track of those blocks,
>>>>
>>> reassembling
>>
>>> or splitting the streamed data as necessary. You could use UDP which
>>>> does guarantee that packets will be kept together, but that protocol
>>>> doesn't guarantee delivery.
>>>>
>>>
>>> Thank you for your input.
>>>
>>> Is it guaranteed that at least 1 byte will be sent each time? For
>>> example, if I know the data length...
>>>
>>> <?php
>>> $input = '';
>>>
>>> for ($i=0; $i<$dataLength; $i++) {
>>>    // Read 1 byte at a time
>>>    if (($data = @socket_read ($socket, 1, PHP_BINARY_READ)) !==
>>> false) {
>>>        $input .= $data;
>>>    }
>>> }
>>>
>>> return $input;
>>> ?>
>>>
>>> Or is this a completely unreasonable and unnecessary way to get the
>>> data?
>>>
>>
>> While I have written a lot of code to manage sockets over the years, and
>> coded a UDP/IP stack, I have never done it in PHP. And unfortunately, I
>> don't have time to experiment right now. My boss is waiting for the next
>> product release from me.
>>
>> Getting one byte at a time is somewhat wasteful, as it requires more
>> system calls than necessary. That's a lot of wasted overhead.
>>
>> Whether you always get one or more bytes depends on a number of factors,
>> including whether the calls PHP uses are blocking or non-blocking, plus
>> there may be ways to switch the socket back and forth.
>>
>> Have you tried doing a Google search on the group of PHP functions you
>> expect to use. That should come up with some sample code to look at.
>>
>> Bob McConnell
>>
>
> I agree that one byte at a time is wasteful. I'm sure others haven't
> implemented something along these lines, but I wrote a much more efficient
> way to make sure I grab all the data of a known length...
>
> <?php
> function readSocketForDataLength ($socket, $len)
> {
>    $offset = 0;
>    $socketData = '';
>
>    while ($offset < $len) {
>        if (($data = @socket_read ($socket, $len - $offset,
> PHP_BINARY_READ)) === false) {
>            return false;
>        }
>
>        $offset += strlen ($data);
>        $socketData .= $data;
>    }
>
>    return $socketData;
> }
> ?>
>
> If not all the data is obtained on a read, it will loop until the amount of
> data is the same as the length requested. This is working quite well.
>
> Thanks Bob and the others!
>
> ~Philip
>
>
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
socket related:
Does this solution work on both, blocking and non-blocking sockets ?
And what about different read method?

solution related:
Does strlen works fine with binary data?
Does this snippet work for sending/receiving multibytes strings?

-- 
Martin Scotta

Reply via email to