当前位置:  开发笔记 > 编程语言 > 正文

Perl套接字如何在Linux下解析主机名?

如何解决《Perl套接字如何在Linux下解析主机名?》经验,为你挑选了1个好方法。

我有一个(据我所知)完美的Linux设置(Ubuntu 8.04),其中所有工具(nslookup,curl,wget,firefox等)都能够解析地址.但是,以下代码失败:

$s = new IO::Socket::INET(
    PeerAddr => 'stackoverflow.com',
    PeerPort => 80,
    Proto => 'tcp',
);

die "Error: $!\n" unless $s;

我验证了以下内容:

Perl能够使用gethostbyname解析地址(即下面的代码可以工作):

my $ret = gethostbyname('stackoverflow.com'); print inet_ntoa($ret);

原始源代码在Windows下运行

这是它应该如何工作(即它应该解析主机名),因为LWP试图使用这种行为(实际上我通过尝试调试为什么LWP不能为我工作而偶然发现问题)

运行脚本不会发出DNS请求(因此它甚至不会尝试解析名称).用Wireshark验证

tye.. 7

从快速看,下面的代码来自IO :: Socket :: INET

sub _get_addr {
    my($sock,$addr_str, $multi) = @_;
    my @addr;
    if ($multi && $addr_str !~ /^\d+(?:\.\d+){3}$/) {
        (undef, undef, undef, undef, @addr) = gethostbyname($addr_str);
    } else {
        my $h = inet_aton($addr_str);
        push(@addr, $h) if defined $h;
    }
    @addr;
}

建议(如果您查看此代码的调用者)添加MultiHomed => 1,到您的代码的解决方法.

如果没有解决方法,上面的代码似乎尝试inet_aton("hostname.com")使用Socket.pm中的inet_aton()进行调用.这对Win32和Unix都适用,所以我想这就是破坏的地方.

有关inet_aton的源代码,请参阅Socket.xs:

void
inet_aton(host)
    char *  host
    CODE:
    {
        struct in_addr ip_address;
        struct hostent * phe;

        if (phe = gethostbyname(host)) {
            Copy( phe->h_addr, &ip_address, phe->h_length, char );
        } else {
            ip_address.s_addr = inet_addr(host);
        }

        ST(0) = sv_newmortal();
        if(ip_address.s_addr != INADDR_NONE) {
            sv_setpvn( ST(0), (char *)&ip_address, sizeof ip_address );
        }
    }

Perl gethostbyname()似乎比C gethostbyname()效果更好.



1> tye..:

从快速看,下面的代码来自IO :: Socket :: INET

sub _get_addr {
    my($sock,$addr_str, $multi) = @_;
    my @addr;
    if ($multi && $addr_str !~ /^\d+(?:\.\d+){3}$/) {
        (undef, undef, undef, undef, @addr) = gethostbyname($addr_str);
    } else {
        my $h = inet_aton($addr_str);
        push(@addr, $h) if defined $h;
    }
    @addr;
}

建议(如果您查看此代码的调用者)添加MultiHomed => 1,到您的代码的解决方法.

如果没有解决方法,上面的代码似乎尝试inet_aton("hostname.com")使用Socket.pm中的inet_aton()进行调用.这对Win32和Unix都适用,所以我想这就是破坏的地方.

有关inet_aton的源代码,请参阅Socket.xs:

void
inet_aton(host)
    char *  host
    CODE:
    {
        struct in_addr ip_address;
        struct hostent * phe;

        if (phe = gethostbyname(host)) {
            Copy( phe->h_addr, &ip_address, phe->h_length, char );
        } else {
            ip_address.s_addr = inet_addr(host);
        }

        ST(0) = sv_newmortal();
        if(ip_address.s_addr != INADDR_NONE) {
            sv_setpvn( ST(0), (char *)&ip_address, sizeof ip_address );
        }
    }

Perl gethostbyname()似乎比C gethostbyname()效果更好.

推荐阅读
黄晓敏3023
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有