Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

IO::Socket should be readable, but isn't....

by blogan (Monk)
on Mar 03, 2002 at 19:57 UTC ( [id://149008]=perlquestion: print w/replies, xml ) Need Help??

blogan has asked for the wisdom of the Perl Monks concerning the following question:

I'm working on a project that works with a line by line protocols (POP3 and SMTP). I'm running into a problem where IO::Select->can_read is reporting that a socket doesn't have anything on it when it does. This only happens when I'm reading a bunch of lines from the socket (retrieving a message). Here's a boiled down test example that should connect, get a specified message, and then quit. I should probably be keeping track of states to know what to send next, but this is just to figure out the can_read problem. It hangs on the same line all the time, but will print everything out if more data comes in on the socket.
#!/usr/bin/perl use IO::Socket; use IO::Select; $user = shift || die "Usage: $0 user password server msgnum\n"; $pass = shift || die "Usage: $0 user password server msgnum\n"; $server = shift || die "Usage: $0 user password server msgnum\n"; $msgnum = shift || die "Usage: $0 user password server msgnum\n"; sub setgreen { print "\033[00;32m"; } sub setred { print "\033[00;31m"; } sub setnormal { printf "\033[00m"; } $dstsock = IO::Socket::INET->new( PeerAddr => $server, PeerPort => 110, Proto => 'tcp'); $readables = IO::Select->new(); $readables->add($dstsock); $notdone = 1; while ($notdone) { my @ready = $readables->can_read(0); foreach $sock (@ready) { $data = <$dstsock>; if ($data) { setred; print "$data"; setnormal; if ($data =~ /^\+OK Qpopper/) { print $dstsock "user $user\r\n"; setgreen(); print "user $pass\r\n"; setnormal; } if ($data =~ /^\+OK Password/) { print $dstsock "pass $pass\r\n"; setgreen(); print "pass $pass\r\n"; setnormal; } if ($data =~ /^\+OK $user/) { print $dstsock "retr $msgnum\r\n"; setgreen(); print "retr $msgnum\r\n"; setnormal; } if ($data =~ /^\.$/) { print $dstsock "quit\r\n"; setgreen(); print "quit\r\n"; setnormal; } } else { $notdone = 0; close $dstsock; close $srcsock; } } }

Replies are listed 'Best First'.
Re: IO::Socket should be readable, but isn't....
by chipmunk (Parson) on Mar 03, 2002 at 21:09 UTC
    I'm not certain, but your problem may be related to this caveat from the documentation for select:
    WARNING: One should not attempt to mix buffered I/O (like `read' or <FH>) with `select', except as permitted by POSIX, and even then only on POSIX systems. You have to use `sysread' instead.
    This is because, although select will tell you that there is some input waiting on the filehandle, there may not be enough input available to fill the buffer used by read() or <FH>. If this happens, the read will block waiting for more input. Switching to sysread() may fix your script.
      I knew I couldn't use it with read, but I thought I might be find with using select, because the way POP3 works is that the client or server will never send a partial line. I did use a version that worked using sysread(), the downside was that I want to be able to work with data 1 line at a time. I suppose I can use a system where I use sysread to fill a buffer and then use another function to extract a line from the buffer.
Re: IO::Socket should be readable, but isn't....
by chromatic (Archbishop) on Mar 03, 2002 at 20:58 UTC
    Looking at the man page for select on my box reveals that it may return immediately with a timeout of 0. Increase that to the maximum time you wish to wait for data, and you may have better results. That's just a guess.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://149008]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-04-24 05:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found