Delphi 7 Indy IdFTP 没有 send/receive 数据

Delphi 7 Indy IdFTP did'nt send/receive data

2 年前,我为使用 Delphi 7 和 Indy 的人编写了一个简单的 client/server 程序,通过 Internet 发送和接收一些数据。 我用 TIdFTP 连接到他们的服务器并在上面获取和放置数据。

它运行了 2 年,效果很好。今天, 他们在另一个城市开了另一个办公室,他们想把程序复制到他们新的办公室电脑上,但是程序在那里不起作用。

程序连接成功,但无法读取目录列表,也无法放入或获取数据。如果它尝试将文件发送到服务器,他们最终只会得到一个空文件!

首先,我认为问题出在防火墙或类似问题上,但该程序在有和没有防火墙的 Win XP、7 或 8 上都无法运行(我在所有防病毒软件上禁用了防火墙,甚至 Windows 防火墙)。我知道防火墙没问题

他们的计算机(不起作用)和另一台计算机(起作用)之间只有两点不同:

  1. ISP
  2. 路由器

他们有 4 台电脑和一个电缆路由器。

现在我想问你:

  1. ISP 能这样屏蔽流量吗?连接成功,但没有任何其他(放置、获取、列表)?

  2. 路由器有什么问题吗TIdFTP?

我能做什么?

我的代码很简单,像这样:

idftp1.Port:=21;
idftp1.Host:='ftp.***.ir';
idftp1.Username:='ftp@***.ir';
idftp1.Password:='***';
idftp1.Connect;
fp:='c:\download';
idftp1.ChangeDir('***');
idftp1.Put(fp+'\message.rhp','message.rhp',false);

这听起来像是网络路由问题。

FTP 使用多个 TCP 连接。主要命令连接,次要数据传输连接。第一个始终是出站,因此不太可能在客户端被阻止。其他连接默认为入站连接,因此很可能在客户端被阻止。这可能是 ISP 阻塞或路由器阻塞,两者都有可能。

ISP 可能会阻止入站连接。 ISP 通常不喜欢用户 运行 他们自己的服务器而不支付额外费用。 FTP 默认情况下,传输以类服务器模式运行。与 ISP 核实入站连接是否被阻止。

FTP 不是路由器友好的协议。传输以两种模式之一运行 - 主动或被动。

  • 在Active模式下(默认),当FTP客户端要传输数据时,它打开一个监听端口,并将IP和端口报告给FTP服务器通过 PORTEPRT 命令,然后 FTP 服务器连接到此端口。

    这是到 FTP 客户端的入站连接,因此需要在客户端的路由器上配置端口转发。有些路由器是 FTP-aware,可以识别这些 FTP 命令,因此可以自动设置端口转发。

    然而,大多数路由器都没有这么智能,需要管理员手动设置端口转发。

    除非路由器支持 uPNP,在这种情况下 FTP 客户端可以可编程设置端口转发。 TIdFTP 没有实现 uPNP,但是有第 3 方 uPNP 库可用,以及在 Windows 本身中实现的 uPNP API。

    如果此端口转发设置不正确,FTP 客户端无法与 FTP 服务器交换数据。在Put()的情况下,如果服务器在传输失败时不删除文件(以便稍后恢复),这很容易导致服务器上出现空文件。

  • 在被动模式下,当FTP客户端要传输数据时,它向FTP服务器发送PASVEPSV命令,然后打开一个监听端口并将IP和端口报告给FTP客户端,然后FTP客户端连接到这个端口。

    这是来自 FTP 客户端的出站连接,因此不太可能被 ISP 阻止,并且不需要客户端路由器上的任何端口转发。

当无法建立数据传输连接时,在任一模式下,FTP 服务器应通过命令连接向 FTP 客户端报告错误消息,从而导致 TIdFTP.List()TIdFTP.Get()TIdFTP.Put() 方法在您的代码中引发异常。如果那没有发生,那就是出了问题。

那么,你能做什么?最简单的尝试是将 TIdFTP.Passive 属性 设置为 True,这样所有数据传输连接都是出站的。这通常足以避免任何路由问题。

使用嗅探器查看网络流量。

最可能的原因是您的 FTP 客户端默认使用 PORT 命令(至少在一段时间之前由相应的 RFC 强制执行),这在不支持的 NAT 后不起作用DPI.

但这确实可以发生在网络通信的任何阶段——从您机器上的某些安全软件到网络设置问题、公司防火墙,再到 ISP 和目标服务器引起的限制。没有看到流量,就无话可说了。