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"; }

In reply to Re: Non-blocking connect() and gethostbyname()? by Thelonius
in thread Non-blocking connect() and gethostbyname()? by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.