Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Re: use sysread to read non-blocking filehandle

by Corion (Pope)
on Nov 04, 2014 at 12:56 UTC ( #1106021=note: print w/replies, xml ) Need Help??

in reply to use sysread to read non-blocking filehandle

while ($bytes_read) { my $buf; $bytes_read = sysread($out, $buf, $blocksize); ...

Your code leaves the loop as soon as there is nothing to read on a socket.

while( <$fh> ) will read things until it encounters a newline.

Replies are listed 'Best First'.
Re^2: use sysread to read non-blocking filehandle
by x12345 (Novice) on Nov 04, 2014 at 13:06 UTC
    If there is nothing to read,it means the sysread has finished all the reading, I should see something in the results?


      Not exactly--it can also mean "I haven't received a response yet". So you're probably terminating the loop before the other side ever had a chance to reply. (Considering the timing, you may be exiting before the other computer even received the request.)

      Update: It can also mean "The network is really busy, so the next packet hasn't arrived yet." That could be a problem if you've received only part of your response.


      When your only tool is a hammer, all problems look like your thumb.

        Could you show me how to change my code to get the results?

      If there is nothing to read,it means the sysread has finished all the reading?

      Or an error. You got error EAGAIN. That error signifies that sysread should block, but the file handle is non-blocking.

      EAGAIN or EWOULDBLOCK: The file descriptor fd refers to a socket and has been marked nonblocking (O_NON-BLOCK), and the write would block. POSIX.1-2001 allows either error to be returned for this case, and does not require these constants to have the same value, so a portable application should check for both possibilities.

      What you want:

      my $buf; while (1) { my $rv = sysread($out, $buf, 64*1024, length($buf)); if (!defined($rv) && !$!{EAGAIN} && !$!{EWOULDBLOCK}) { die $!; } if (defined($rv) && !$rv) { last; } ... whatever it is you wanted to do instead of blocking ... } print $buf;
      I found the problem in my loop, after use perl -d debugger, it is the $bytes_read should be "my $bytes_read", in the code, it is defined twice, it is a little bit confused, should have better clear way to do that, but in the code I have, it is like that, and when I rewrite the code, I remove my in frond $bytes_code in the while loop, which was wrong. So it should be
      my $bytes_read = sysread($fh,$bug,$blocksize)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1106021]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (3)
As of 2020-11-28 22:41 GMT
Find Nodes?
    Voting Booth?

    No recent polls found