Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: Non-blocking connect() and gethostbyname()?

by Thelonius (Priest)
on Oct 28, 2006 at 14:38 UTC ( [id://581081]=note: print w/replies, xml ) Need Help??


in reply to Non-blocking connect() and gethostbyname()?

For all this, I'm assuming that you're using a big select() to wait for all I/O and that you're not doing threads. (Threads would be one solution to all this, if they're supported on your perl/OS).

About gethostname():
I don't see any nonblocking DNS library on CPAN, so I think what you would have to do is create a pipe (or socket pair), fork, do the lookup in the child process and return the result via the pipe (you add the pipe to your select in the parent).

About connect():
Several possibilities:

  1. You don't have to use IO::Socket. You can use the plain socket functions, as documented in perlfunc. You can use the sockets returned by the socket() call in IO::Select->add or you can use plain select(), managing the bit vectors yourself (yuck).
  2. If you want an IO::Socket::INET object, you can create the socket with IO::Socket::INET new without a PeerAddr, then do the connect yourself. E.g.
    my $sock = IO::Socket::INET->new(Proto => 'tcp', Blocking => 0) or die "Socket error: $!\n"; my $iaddr = inet_aton($remote) || die "no host: $remote"; my $paddr = sockaddr_in($port, $iaddr); my $ret = connect($sock, $paddr); if (!$ret && ! $!{EINPROGRESS}) { die "Connect error: $!\n"; } # then select(), etc.
  3. Or, you could subclass IO::Socket::INET and override the connect method
    use strict; { package NBCSocket; use IO::Socket::INET; use Errno; use Carp; our @ISA = 'IO::Socket::INET'; sub connect { @_ == 2 or croak 'usage: $sock->connect(NAME)'; my $sock = shift; my $addr = shift; my $timeout = ${*$sock}{'io_socket_timeout'}; my $err; my $blocking; $blocking = $sock->blocking(0); if (!connect($sock, $addr)) { if (!$!{EINPROGRESS}) { $err = $!; $@ = "connect: $!"; } } $! = $err if $err; $err ? undef : $sock; } } use IO::Select; use Socket; $| = 1; my $address = shift || die "usage: $0 host:port\n"; $! = 0; my $err; print "Start: ", scalar(localtime), "\n"; my $sock = NBCSocket->new(PeerAddr => $address) or die "Socket error: $!\n"; print "after NBCSocket->new \$! = $!\n"; # of course, you'll probably want to do a select with other sockets $! = 0; my $select = IO::Select->new($sock); if ($select->can_write(5)) { my $peername = $sock->peername; if ($peername) { print "Connected: ", scalar(localtime), ", peername=$peername\n" +; } else { print "Not peername err = $!: ", scalar(localtime), "\n"; } } else { $err = $!; $sock_err = $sock->sockopt(SO_ERROR); print "Did not connect: ", scalar(localtime), "\n"; print "\$!=$err sock_err = $sock_err\n"; }

Replies are listed 'Best First'.
Re^2: Non-blocking connect() and gethostbyname()?
by mpeg4codec (Pilgrim) on Jan 06, 2008 at 02:17 UTC

    I've never used it, but wouldn't Net::ADNS do the trick for asynchronous DNS lookups?

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (2)
As of 2024-06-20 05:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.