Re: Yet Another Autoflush problem -- What's wrong with this code?
From: Walter Roberson (roberson_at_ibd.nrc-cnrc.gc.ca)
Date: 01/24/04
- Next message: Walter Roberson: "Re: "system" commands don't work on my Windows machine"
- Previous message: John W. Kennedy: "Re: Regular expression to find <tr> tags in 2nd level HTML tables"
- In reply to: John Chambers: "Re: Yet Another Autoflush problem -- What's wrong with this code?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 24 Jan 2004 05:32:58 GMT
In article <40118a1e$0$12721$61fed72c@news.rcn.com>,
John Chambers <jmchambers@rcn.com> wrote:
:Ben Morrow wrote:
:> Here is your problem. <$server> will not return until it reads a
:> newline. You either want to set $/ to \1 (which will read a byte at a
:> tyme: not very efficient) or set non-blobking mode and use
:> while (read $server, $line, 1024) {
:> ; or maybe sysread instead.
:So I guess all those FAQs and RTFMs are just red herrings, and
:I was guessing right all along. I wonder why I never ran across
:any comments about this? Others have had to stumbled across the
:same problem. There's gotta be a lot of people trying to send
:data across TCP links in perl, right? And data isn't always in
:the form of ASCII text with newlines at the end of every data
:object, right?
The behaviour is deducible, by reading in perlops that <handle>
is equivilent to readline(*handle) and then reading the perlfunc
documentation of readline as returning the next line delimited
by the current record separator.
More explicit discussion appears in the perlipc documentation in
the section "Interactive Client with IO::Socket"
If the remote server sends data a byte at time, and you need
that data immediately without waiting for a newline (which
might not happen), you may wish to replace the "while" loop
in the parent with the following:
my $byte;
while (sysread($handle, $byte, 1) == 1) {
print STDOUT $byte;
}
Making a system call for each byte you want to read is not
very efficient (to put it mildly) but is the simplest to
explain and works reasonably well.
They are, as they hint, hiding complications in that reading of a
single byte. The sysread() call can potentially return anywhere -up-
to the number of bytes you ask for, dependant on internal buffering.
The maximum number of bytes of pipe data that are guaranteed to be handled
atomically is 512 for any POSIX compliant system; the SGI IRIX systems
I use most provide up to 10240 bytes atomically.
(For more information about these limits on a POSIX system, see
<limits.h> and the sysconf() and pathconf() calls, and the
constants _POSIX_PIPE_BUF and PIPE_BUF .)
When you are reading from a device (e.g., a tty) instead of a pipe, then
all guarantees about minimum I/O sizes are off: essentially you get
whatever became available between interrupts. When data is flowing
at a steady rate and you are in a tight loop, the read sizes tend to
be consistant, but not necessarily very big, and the first read
isn't necessarily going to be the same size. In one of the tests I
did, I tended to get 3 bytes on the first read and then groups of 10
bytes when running at 38400 bps across a serial port... but
that was only a tendancy, and it varied with load and was
pom-dependent.
The net result of these uncertainties is that if you are using
sysread() with a buffer size greater than 1 and there is any
possibility that the data might not arrive atomically, then you need
to explicitly examine the number of bytes that arrived and cycle back
until you get the full number of bytes that you want to read in
this trip. As sysread() does not pay attention to line boundaries,
you will probably need to decrement your buffer size by the number
of bytes that arrived, and probably need to munge the offset within
the buffer to be stored into. Once you've seen the resulting code
a couple of times, it's easy to recognize.
-- How does Usenet function without a fixed point?
- Next message: Walter Roberson: "Re: "system" commands don't work on my Windows machine"
- Previous message: John W. Kennedy: "Re: Regular expression to find <tr> tags in 2nd level HTML tables"
- In reply to: John Chambers: "Re: Yet Another Autoflush problem -- What's wrong with this code?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|