我们公司的笔记本电脑通过局域网(工作场所)或无线局域网(会议室)上网。根据它们上网的方式,它们从DHCP获得不同的ip地址。服务器上的某个Perl应用程序使用Net::FTP从客户机(例如上面的笔记本电脑)复制文件。这段代码看起来像这样:
# don't wait for ftp-timeout if the host is not reachable
my $alive = Net::Ping::External(host => $clnt_host);
if ($alive) {
$ftp = Net::FTP->new($clnt_host, Debug => 0, Timeout => 200)
or return "Cannot connect to $clnt_host: $@n";
....
....
}
else {
dbgout(1, "Host $clnt_host unreachable.n");
$st = "'FTPGETFAILED'";
return ($st);
}
有时上面的代码不起作用:Net::Ping::External()返回"alive",但Net::FTP->new()获得"timeout"。显然"FTP"one_answers"ping"解析主机名是不同的。
在操作系统上ping解析如下:
C:Usersconverter>ping -n 1 lap314-034
Ping wird ausgeführt für lap314-034.domain.de [10.140.12.110] mit 32 Bytes Daten:
Antwort von 10.140.12.110: Bytes=32 Zeit=2ms TTL=127
但是,"nslookup"返回2种可能性:
C:Usersconverter>nslookup lap314-034
Server: domaincontroller.domain.de
Address: 123.123.123.123
Name: lap314-034.domain.de
Addresses: 10.192.3.145
10.140.12.110
非活动IP地址从nslookup在第一个位置返回。
我猜想Net::FTP也使用这个地址连接到客户端。
我如何"说服"FTP在连接中使用活动DNS条目?
=============================================================
谢谢你的回答。我听从了你的建议。解决方案基于:http://code.activestate.com/lists/perl-win32-users/32624/
#------------------------------------------------------------------
sub getActiveIP {
#------------------------------------------------------------------
my $hostname = shift;
my $host = (gethostbyname ($hostname))[0] or return undef;
my @addr = gethostbyname ($host);
# delete the first 4 array elements
splice @addr, 0, 4;
foreach (@addr) {
my $IPstr = sprintf ("%s", &inet_ntoa ($_));
my $alive = ping(host => $IPstr);
if ($alive) {
return $IPstr;
}
}
return undef;
}
然而,我相信一个广泛的perl库不应该让用户感到这样的惊讶。
我如何"说服"FTP在连接中使用活动DNS条目?
没有好的方法让Net::FTP决定它。相反,您应该在Net::FTP之外确定它,然后使用可用的IP地址而不是Net::FTP中的主机名。
也许你可以只使用新版本的Net::FTP (Net::FTP> 3.0),它可以使用IO::Socket::IP而不是IO::Socket::INET作为底层模块。该模块可以尝试为主机名返回的所有IP地址,直到获得成功的连接。但是这些重试会对每个连接进行,也就是控制连接和每个数据传输。由于与非活动主机的连接只有在超时后才会失败,所以一切都将非常缓慢。
解决方案似乎很明显:获取IP地址,ping它们,找出哪个是活动的,并在Net::FTP
构造器中使用IP地址而不是主机名。