使用 Perls Net::FTP 从 Windows 主机获取文件
Getting files from Windows host with Perls Net::FTP
我们公司的笔记本电脑上网要么是LAN(工作场所),要么是WLAN(会议室)。根据他们上网的方式,他们从 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() returns "alive",但是 Net::FTP->new() 得到一个 "timeout" .
显然 "FTP" 和 "ping" 解析主机名的方式不同。
OS ping reslove 如下:
C:\Users\converter>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" returns 2 种可能性:
C:\Users\converter>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 也使用这个地址连接到客户端。
如何"convince" 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-library不应该让用户感到如此惊讶。
How can I "convince" FTP to use the active DNS entry for the connection?
没有什么好办法让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 地址而不是主机名。
我们公司的笔记本电脑上网要么是LAN(工作场所),要么是WLAN(会议室)。根据他们上网的方式,他们从 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() returns "alive",但是 Net::FTP->new() 得到一个 "timeout" .
显然 "FTP" 和 "ping" 解析主机名的方式不同。
OS ping reslove 如下:
C:\Users\converter>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" returns 2 种可能性:
C:\Users\converter>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 也使用这个地址连接到客户端。
如何"convince" 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-library不应该让用户感到如此惊讶。
How can I "convince" FTP to use the active DNS entry for the connection?
没有什么好办法让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 地址而不是主机名。