【问题标题】:IPv6 with perl on windows not working在 Windows 上使用 perl 的 IPv6 无法正常工作
【发布时间】:2012-07-30 00:22:22
【问题描述】:

转帖http://perlmonks.org/index.pl?node_id=984750

perl windows IPv6 的可能重复项) 我尝试了以下示例:https://metacpan.org/module/IO::Socket::IP

use IO::Socket::IP -register;

my $sock = IO::Socket->new(
   Domain    => PF_INET6,
   LocalHost => "::1",
   Listen    => 1,
) or die "Cannot create socket - $@\n";

print "Created a socket of type " . ref($sock) . "\n";

它给出的输出为: 无法创建套接字 - 没有与节点名关联的地址

我正在使用 ActiveState perl 5.14.2 并在其上构建了 IO::Socket::IP 模块。

ping结果如下:

c:\>ping ::1

Pinging ::1 with 32 bytes of data:
Reply from ::1: time<1ms
Reply from ::1: time<1ms
Reply from ::1: time<1ms
Reply from ::1: time<1ms

Ping statistics for ::1:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms

如果我使用 IPv4 样式的环回地址 127.0.0.1,上面的代码运行良好。 我想知道我错过了什么。

更新:

我刚刚清理了 perl 设置和路径,并从新安装了 perl 5.14.2 http://www.activestate.com/activeperl/downloads

然后我尝试了以下简单代码:

use strict;
use warnings;

use Socket qw(getaddrinfo SOCK_STREAM AI_PASSIVE  );

my ( $err, @res ) = getaddrinfo( "::", 8086, {
    socktype => SOCK_STREAM,
    flags => AI_PASSIVE,
} );
die $err if $err;

它以以下错误结束: 在 c:\IPv6.pl 第 10 行没有与节点名关联的地址。

但是使用 127.0.0.1 它会返回正确的值。

我使用的是 windows 2008 R2 机器,在我的另一个 windows 机器上同样运行也失败了。

我刚刚尝试在 Socket.pm 中跟踪此调用,发现调用的是“fake_getaddrinfo”而不是真正的 getaddrinfo。似乎 XSLoader 要么无法从 Socket.dll 找到/加载 getaddrinfo,要么 Socket.dll 根本没有 getaddrinfo。 可能是什么原因?

下面使用 Socket6 的类似代码在相同的设置下正常工作:

use Socket;
use Socket6;

@res = getaddrinfo('::', 8086, AF_UNSPEC, SOCK_STREAM);

while(scalar(@res)>=5){

    ($family, $socktype, $proto, $saddr, $canonname, @res) = @res;
    ($host, $port) = getnameinfo($saddr, NI_NUMERICHOST | NI_NUMERICSERV);
    print ("\nhost= $host port = $port");
    socket(Socket_Handle, $family, $socktype, $proto) || next;
    bind(Socket_Handle,$saddr  )  || die "bind: $!";
    listen(Socket_Handle, 5) || die "listen: $!";

    ($host, $port) = getnameinfo($saddr, NI_NUMERICHOST | NI_NUMERICSERV);
    print ("\nReady for connections \nhost= $host port = $port");
    $paddr = accept(Client, Socket_Handle);
}

所以我什至不能责怪设置或系统 dll。 perl 对 windows 的 activestate 构建的内置 IPv6 支持是否存在问题?

【问题讨论】:

  • sn-p 在 Linux 上完美运行,所以这可能是一个平台错误
  • 我怀疑上面的代码没有使用正确设置 scope_id 和 flowspec 字段来初始化 ipv6 套接字地址结构。在 C 代码中,绑定到 ::1 的典型方法是调用 getifaddrs() 并以 ::1 作为 IP 或“lo”作为适配器名称来枚举适配器。然后使用 ifaddrs->ifa_addr 作为要绑定的套接字地址。我不知道 perl 是否有办法做到这一点。
  • 您是否允许此套接字通过 Windows 防火墙?
  • @anttix : 令人惊讶的是,同样的代码 sn-p 在我的 linux 机器上也能很好地工作!

标签: windows perl ipv6


【解决方案1】:

正如vinsworldcom on perlmonks.org 所述,要使用 IPv6 套接字,您需要安装 Socket6 模块。只要你通过 cpan 安装它,代码 sn-p 就可以正常工作了。

【讨论】:

    猜你喜欢
    • 2020-08-04
    • 2016-04-11
    • 1970-01-01
    • 2019-09-01
    • 2021-01-14
    • 2021-10-30
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    相关资源
    最近更新 更多