Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

Re: IO::Select - reading multiple lines

by zentara (Archbishop)
on Jul 07, 2011 at 12:04 UTC ( #913167=note: print w/replies, xml ) Need Help??

in reply to IO::Select - reading multiple lines

You might want to use sysread instead of my $data = <$fh>. See sysread and syswrite in tcp sockets for example.
# as a start change my $line = <$fh>; #to sysread $fh, my $line, 1024;,
The basic issue is that <$fh> does a buffered read from the socket. It won't return from the read call until $/ (defaults to "\n") is encountered on the channel. IO::Select::can_read just means that there is data on the channel, it does not necessarily mean that there is a full record (defined as: a chunk terminated with an occurence of $/) waiting on the channel.

I'm not really a human, but I play one on earth.
Old Perl Programmer Haiku ................... flash japh

Replies are listed 'Best First'.
Re^2: IO::Select - reading multiple lines
by Somni (Friar) on Jul 07, 2011 at 18:53 UTC
    That is indeed the correct solution (to use sysread). However, it's worse than simply because there's no newline.

    select generally doesn't work properly if you mix in buffered reads and writes; select will perpetually think something is readable, or nothing is readable, because the buffering has over-read or under-read on the handle.

    This means that whenever you're using select, either directly or indirectly through IO::Select or some event loop, then you must use sysread and syswrite (not print, <$fh>, read(), etc.).

    You often end up doing your own buffering with sysread and syswrite, because often you're still dealing with line-oriented protocols. This is fairly boilerplate stuff, and it's recommended to use an event loop that does most of it for you (e.g. POE, Event, IO::Async, etc.).

Re^2: IO::Select - reading multiple lines
by nagalenoj (Friar) on Jul 14, 2011 at 13:23 UTC

    I've many questions raising now., Let me tell what's in my mind.

    So, is it a very worse idea to use <$fh> to read from a socket? Because, it is failing straight away without doing lot of magic(stuffs) in the code.

    Server side
    while(@ready = $sel->can_read) { if($fh == $lsn) { # Accept the socket $new = $lsn->accept; $sel->add($new); print "New client accepted\n"; print $new "abc\n"; print $new "abcd\n"; print $new "abcde\n"; print $new "abcdef\n"; } else { # Process socket $a = <$fh> ; if (not defined $a) { $sel->remove($fh); $fh->close; print "Client closed\n"; } else { print $a; } } }
    Client side
    while(@ready = $sel->can_read) { foreach $fh (@ready) { my $rr = <$fh>; exit if ( not defined $rr ); print $rr; } }

    In the above sample, client is receiving only abc(first message) sent by server. When server quits, can_read is returning and client is receiving the remaining messages, not blocking. Getting messages one after another.

    Then, I tried with sysread as suggested here. When using sysread, should I read byte by byte till '\n'? Because, I don't know the size of the message. Is it a good way to read byte by byte, do concatenation and then process the message?(I don't think so.)

    Please, explain me some way to write a error free way(pleasant way too) to receive messages in socket.. or let me know what am I doing wrong.

      is it a very worse idea to use <$fh> to read from a socket

      Yeah, you are best off using sysread, and there are a few ways to use sysread, depending on your situation, you can put it in various staement forms

      while( sysread $fh, $str, 8192, length $str ) { #or do { $rc = sysread(FH, $buff, 5000000, length($buff)) ; } while ($rc #or if ( sysread( $cli, $buffer, 1024 ) ) {} # etc etc

      I'm not really a human, but I play one on earth.
      Old Perl Programmer Haiku ................... flash japh
        sysread returns 0, only when the other end exits. Getting into blocking mode, which is not desired. I expect the program to wait in select not in sysread.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://913167]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2018-01-22 19:13 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (235 votes). Check out past polls.