问题描述
2年前,我为使用Delphi 7和Indy的人通过Internet发送和接收一些数据编写了一个简单的客户端/服务器程序.我使用 TIdFTP
连接到他们的服务器并在其上获取并放置数据.
2 years ago, I wrote a simple client/server program for someone using Delphi 7 and Indy to send and receive some data through the Internet.I used TIdFTP
to connect to their server and get and put data on it.
它运行了2年.今天,他们已经在另一个城市开设了另一个办公室,他们想将该程序复制到他们的新办公室计算机上,但是该程序在那儿不起作用.
It worked well for 2 years. Today,they have opened another office in another city, and they want to copy the program to their new office computer, but the program doesn't work there.
程序成功连接,但无法读取目录列表,也无法放入或获取数据.如果它尝试将文件发送到服务器,则它们最终将得到一个空文件!
The program connects successfully, but can't read the directory list, or put or get data. If it tries to send a file to the server, they just end up with an empty file!
首先,我认为问题出在防火墙或类似问题上,但是该程序在带有和不带有防火墙的Win XP,7或8上均无法运行(我在所有防病毒软件上都禁用了防火墙,甚至Windows防火墙).我知道防火墙没有问题.
First, I thought the problem is with the firewall, or something like that, but the program doesn't work on Win XP, 7, or 8 with and without a firewall (I disabled firewalls on all the antivirus, and even the Windows firewall). I know there is no problem with a firewall.
他们的计算机(不起作用)和另一台计算机(起作用)之间只有两处不同:
There are only two things different between their computer (that doesn't work) and the other computer (that does work):
- ISP
- 路由器
他们有4台计算机和一台有线路由器.
They have 4 computers and a cable router.
现在我想问你:
-
ISP可以像这样阻止流量吗?连接成功,但没有其他任何东西(放置,获取,列出)?
can the ISP block traffic like this? Connect successful, but not anything else (put, get, list)?
关于路由器和 TIdFTP
的任何信息吗?
is there anything about the router and TIdFTP
?
我该怎么办?
我的代码非常简单,就像这样:
my code is very simple like this:
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阻塞,也可能是路由器阻塞.
This sounds like a network routing issue.
FTP uses multiple TCP connections. The main command connection, and secondary data transfer connections. The first is always outbound, so NOT likely to be blocked on the client side. The other connections are inbound by default, and so VERY likely to be blocked on the client side. This can be either an ISP blockage or a router blockage, both are a possibility.
ISP可能会阻止入站连接.ISP通常不喜欢用户自己运行服务器,而无需为此付费.默认情况下,FTP传输以类似于服务器的模式运行.与ISP检查入站连接是否被阻止.
An ISP may block inbound connections. ISPs don't generally like users running their own servers without paying extra for it. FTP transfers act in a server-like mode by default. Check with the ISP if inbound connections are blocked or not.
FTP是不支持路由器的协议.传输采用两种模式之一-主动或被动.
FTP is a not a router-friendly protocol. Transfers operate in one of two modes - Active or Passive.
-
在活动模式(默认)下,当FTP客户端要传输数据时,它将打开一个侦听端口,并通过
PORT
或EPRT
命令,然后FTP服务器连接到该端口.
In Active mode (the default), when the FTP client wants to transfer data, it opens a listening port and reports the IP and port to the FTP server via a
PORT
orEPRT
command, and then the FTP server connects to this port.
这是与FTP客户端的入站连接,因此需要在客户端的路由器上配置端口转发.一些路由器可以识别FTP,并且可以识别这些FTP命令,因此可以自动设置端口转发.
This is an inbound connection to the FTP client, so it requires port forwarding be configured on the client's router. Some routers are FTP-aware and can recognize these FTP commands so port forwarding can be setup automatically.
但是,大多数路由器都不是很聪明,需要管理员手动设置端口转发.
However, most routers are not this smart, requiring an administrator to setup port forwarding manually.
除非路由器支持uPNP,否则FTP客户端可以以编程方式设置端口转发. TIdFTP
没有实现uPNP,但是有第三方的uPNP库以及Windows本身实现的uPNP API.
Unless the router supports uPNP, in which case the FTP client can setup port forwarding programmably. TIdFTP
does not implement uPNP, but there are 3rd party uPNP libraries available, as well as a uPNP API implemented in Windows itself.
如果未正确设置此端口转发,则FTP客户端无法与FTP服务器交换数据.对于 Put()
而言,如果在传输失败时服务器没有删除该文件,则很容易导致服务器上的文件为空(以便以后恢复).
If this port forwarding is not setup correctly, the FTP client cannot exchange data with the FTP server. In the case of Put()
, this could easily result in an empty file on the server, if the server does not delete the file when the transfer fails (to facilitate later resuming).
在被动模式下,当FTP客户端要传输数据时,它会向FTP服务器发送 PASV
或 EPSV
命令,然后打开监听端口,并将IP和端口报告给FTP客户端,然后FTP客户端连接到该端口.
In Passive mode, when the FTP client wants to transfer data, it sends a PASV
or EPSV
command to the FTP server, which then opens a listening port and reports the IP and port to the FTP client, and then the FTP client connects to this port.
这是来自FTP客户端的出站连接,因此它不太可能被ISP阻止,并且不需要在客户端路由器上进行任何端口转发.
This is an outbound connection from the FTP client, so it is not likely to be blocked by an ISP, and does not require any port forwarding on the client's router.
在任何一种模式下都无法建立数据传输连接时,FTP服务器应通过命令连接向FTP客户端报告错误消息,从而导致 TIdFTP.List()
, TIdFTP.Get()
和 TIdFTP.Put()
方法在您的代码中引发异常.如果那没有发生,那就出问题了.
When a data transfer connection cannot be established, in either mode, the FTP server should be reporting an error message to the FTP client over the command connection, causing the TIdFTP.List()
, TIdFTP.Get()
and TIdFTP.Put()
methods to raise an exception in your code. If that is not happening, something is going wrong.
那么,你能做什么?最简单的尝试是将 TIdFTP.Passive
属性设置为True,以便所有数据传输连接都出站.通常,这足以避免任何路由问题.
So, what can you do? The simplest thing to try is set the TIdFTP.Passive
property to True so all data transfer connections are outbound. This is usually enough to avoid any routing issues.
这篇关于Delphi 7 Indy IdFTP没有发送/接收数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!