【问题标题】:Domain name to IPv6 address in PerlPerl中的域名到IPv6地址
【发布时间】:2014-08-25 19:46:35
【问题描述】:

我有以下 Perl 代码将域名转换为 IP 地址。它在 IPv4 中运行良好。

$host = "example.com";
$ip_address = join('.', unpack('C4',(gethostbyname($host))[4]));

但是,如果它是仅限 IPv6 的域名,例如“ipv6.google.com”,则它不起作用。

如何通过一行代码(首选 CORE 库)获取 IPv6 IP 地址?

$host = "ipv6.google.com";
$ip_address = ???

【问题讨论】:

  • 什么版本的 perl?
  • 我正在查看 Perl 5.10 及更高版本

标签: perl sockets ip-address ipv6 gethostbyname


【解决方案1】:

在5.14及以上,可以使用核心Socket

use 5.014;
use warnings;
use Socket ();

# protocol and family are optional and restrict the addresses returned
my ( $err, @addrs ) = Socket::getaddrinfo( $ARGV[0], 0, { 'protocol' => Socket::IPPROTO_TCP, 'family' => Socket::AF_INET6 } );
die $err if $err;

for my $addr (@addrs) {
    my ( $err, $host ) = Socket::getnameinfo( $addr->{addr}, Socket::NI_NUMERICHOST );
    if ($err) { warn $err; next }
    say $host;
}

对于早期的 perls,相同的功能可从 CPAN 上的 Socket::GetAddrInfo 获得。

【讨论】:

  • 套接字是双活的。是否有任何理由安装 Socket::GetAddrInfo 而不是升级 Socket?
  • 我在使用 Perl 5.16 Windows 时遇到以下错误。 a.pl 第 7 行不支持 ai_family。
  • @Micheal C.,已通过升级 Socket (cpan Socket) 复制和解决
  • @ikegami 我有最新的 Socket 2.014 但同样的错误。
  • 我发现在每次调用时指出包含某些内容的包更简洁,尤其是常量。
【解决方案2】:

Net::DNS也可以帮你:

#!/usr/bin/perl -w                                                                                                  
use strict;
use warnings;

use Net::DNS;

my $res   = Net::DNS::Resolver->new;
my $query = $res->query("ipv6.google.com", "AAAA")
    or die "query failed: ", $res->errorstring;

foreach my $rr (grep { $_->type eq 'AAAA' } $query->answer) {
    print $rr->address, "\n";
}

输出:

2607:f8b0:4010:801:0:0:0:1005

【讨论】:

  • 请注意,直接访问 DNS 而不是使用系统的名称查找接口 (getaddrinfo) 会隐藏主机文件条目。
  • 无论如何要避免使用 Net::DNS ?
  • 拒绝投票,因为:您永远不应该直接关注 DNS,除非这是您的全部功能 - 执行某种特定于 DNS 的查找。在 99.9% 的情况下,程序不是。相反,他们只想使用系统解析器getaddrinfo。查看其他答案。
猜你喜欢
  • 2011-08-24
  • 1970-01-01
  • 2011-08-31
  • 2013-07-20
  • 2016-04-18
  • 2011-06-15
  • 2013-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多