I can post example code if you want, but it's easy to describe. I connect/accept a socket between two processes and set the socket to not use buffering ($|=1).
One side writes several messages in a row, lets call them mesgA, mesgB, mesgC, sleeps a while then sends mesgD. The other side is in a loop that uses select() to look for incoming messages and processes 1 message each time select says a message is available.
Eg:
The above code always sees mesgA, but doesn't see mesgB etc until the other side sends mesgD when select() finally realizes more data is on the socket.$rin = ''; vec($rin,fileno($sd),1) = 1; $nfound = select($rin, undef, undef, 1.0); if ($nfound) { if ($line = <$sd>) { ... } else { ... knows other side closed the socket ... } }
The problem isn't the usual output-buffering problem. I know this because if I modify the receiver to ignore what select() says and simply read from $sd, mesgB and mesgC are always there right away.
I believe the problem is input buffering. select() is probably looking quite literally only at the socket, and mesgB/C probably aren't on the socket anymore, they've probably been buffered by the receiver.
So now finally to the questions: how can I deal with that? I need to either 1. turn off the input buffering so mesgB/C will still be on the socket where select() will see them so I can be notified of their existance, or 2. have something like select() that lets me know more data is available to read (even if it's not technically on the socket).
Basically how am I supposed to know how much data is sitting there for me to read? I need to read however much is there (without blocking).
Really I think it should be select()'s job to look at the socket and the input buffer and return true for that socket if data is available.. that's the point of select.. to ask "will a read block or not".
In reply to select() and input buffering by declan
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |