in reply to sysread()

Good advice above, although be careful of non-blocking mode in a case like this, you could find yourself repeatedly calling sysread when there's nothing to read (which will chew your CPU), or sleeping un-necessarily (which isn't too bad, but not ideal).

Here's an example of using select instead to wait three seconds for a response.

use IO::Select; # Do socket creation and checking... # Now play with IO::Select so we can wait three seconds for # a result. my $selector = IO::Select->new($sock); if ($selector->can_read(3)) { # 3 second timeout. # Do reading and checking stuff... } else { # Waited three seconds and couldn't read. Bummer. }
Note that if you receive a success from ->can_read, but when you do attempt a sysread you receive 0 or undef, it means that the remote end disconnected or (much less likely) an error occured.

See IO::Select for more information on using this wonderful tool.

Cheers,
Paul

P.S. In the code above you're connecting to port 80, whereas SMTP daemons like sendmail usually live on port 25. I assume this is just a typo.

Replies are listed 'Best First'.
Re: Re: sysread()
by geektron (Curate) on Oct 09, 2001 at 10:13 UTC
    another issue i ran into recent with something like this: sysread() doesn't seem to guarantee that the number of bytes read are, in fact, the number of bytes that were actually read. i had to ( with the help of a co-worker ) stick in some 'error-checking' to ensure that sysread DID in fact deliver the requested number of bytes.

    we ended up implementing this:

    sub send_packet { my ($socket, $packet) = @_; my $length = length($packet); my $lengthbuf = pack("N", $length); my $rc = syswrite($socket, $lengthbuf, 4); die "syswrite (length): $!\n" if $rc != 4; my $byteswritten = 0; while ($byteswritten < $length) { my $rc = syswrite($socket, $packet, length($packet)); die "SEND_PACKET: sysread (data): $!\n" if $rc < 0; $packet = substr($packet, $rc, -1); $byteswritten += $rc; } }
    and that fixed some blocking we encountered - even when IO::Select said a socket was readable.