2008-10-02 29 views
3

我有一个(从我可以告诉)完美工作的Linux安装程序(Ubuntu 8.04),其中所有工具(nslookup,curl,wget,firefox等)都能够解析地址。然而,下面的代码失败:Perl套接字在Linux下如何解析主机名?

$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
  • 验证

回答

7

从快看,从IO ::插座:: 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,的变通你的代码。

没有这种解决方法,上面的代码似乎尝试使用Socket.pm中的inet_aton()调用inet_aton("hostname.com")。这在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()为您做得更好。

+0

是的!是!是! :-)这是问题所在。非常感谢你的解决方案。现在我要弄清楚的是如何说服LWP创建一个特殊的socked(启用multihomed选项)。 – 2008-10-02 05:26:30

-1

请确保您有说法

use IO::Socket::INET; 

在您的源代码开头。如果你离开了这一点,你可能收到错误消息:

通过 包“IO ::插座:: INET”

除了无法找到对象的方法“新”,你可能使用Net :: DNS :: Resoler验证DNS是否正在工作,请参阅更多信息here

use Net::DNS; 

my $res = Net::DNS::Resolver->new; 

# Perform a lookup, using the searchlist if appropriate. 
my $answer = $res->search('example.com'); 
+0

我在脚本的开头有use语句。此外,我已经尝试了第二个测试脚本,它的工作原理(就像预期的那样,考虑到gethostbyname的作用),但我仍然有原始问题。 – 2008-10-02 05:02:52

0

请问您是否可以告诉我们您的代码如何失败?你有错误检查代码,但你没有报告错误是什么!

我刚刚尝试了原始代码(在我的Mac OS X机器上增加了“使用IO :: Socket :: INET”,它工作正常。

我怀疑Multihomed选项是一个不必要的黑客攻击,其他问题是您的问题的根源。