使用 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 地址而不是主机名。