问题
I am wanting to resolve a host name to an ip address which is all fine using Socket with the following:
$ip = gethostbyname($host) or die "Can't resolve ip for $host.\n";
$ip = inet_ntoa(inet_aton($host));
This works fine until it hits a host name that no longer resolves to an IP and the code just stops. How can I get my script to continue processing the remainder ip the host names to be resolved.
Ideally I would simply set the $ip
variable to equal ""
.
I have tried even without the die command and the code still stops when it cannot resolve the name to ip.
回答1:
The timeout on gethostbyname
is very, very long. I assume that you kill the program before you can see that it is just taking a long time. It seems that you really need a shorter timeout.†
You can set up your own time-out using alarm. When it goes off a SIGALRM signal is delivered to the process, which would terminate it by default. So we set up a handler for that signal in which a die
is issued, thus turning it into an exception. This is eval
-ed and we get the control back.
eval {
local $SIG{ALRM} = sub { die "Timed out" };
alarm 5; # or what you find most suitable
# your code that may need a timeout
alarm 0;
};
if ($@ and $@ !~ /Timed out/) { die } # re-raise if it was something else
if ($@ and $@ =~ /Timed out/) { # test
print "We timed out\n";
}
If your code completes in less than 5
seconds we get to alarm 0;
which cancels the previous alarm and the program continues. Otherwise the SIGALRM
is made into a die
which is eval
-ed, and thus the signal is caught and the control drops to right after the block. We test whether the die
was indeed due to our alarm and if not we re-raise it.
Also see this post for more comments, and please search for more.
† The Timeout
functionality that exists in the module IO::Socket
is for connect and not for the DNS lookup, which is the culprit here. Thanks to Steffen Ullrich for a comment.
来源:https://stackoverflow.com/questions/44533600/perl-host-to-ip-resolution