我有一个(据我所知)完美的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()效果更好.
从快速看,下面的代码来自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()效果更好.