2015-03-24 280 views
0

我想从FTP下载文件。如果文件很小(通常在1000MB以下),它就可以工作。但是,如果文件很大,我会得到一个EIdReadTimeout。为什么?我应该保持连接活着吗?据我所知,阅读数据有自己的频道,所以我不必保持连接活着。异常类EIdReadTimeout消息'Read timed out'[Indy-IdFTP]

奇怪的是,异常出现在Get(在Get成功下载整个文件之后)的末尾:FTP.Get(Name,TempGzFile,TRUE,FALSE)!

文档:

TIdFTP.ReadTimeout - 毫秒等待一个FTP协议响应的数量。

TIdFTP.TransferTimeout - FTP 客户端的数据通道读取操作的超时值。

默认情况下,ReadTimeout设置为60秒,TransferTimeout设置为10秒。


我使用Delphi XE7(我猜是使用Indy 10)。我的IdFTP的Passive属性设置为false。

+0

删除超时,或使其变大。在任何情况下,下载大文件或未知文件大小都不应该超时,或者应该设置为很长时间。想象一下,有人使用非常慢的互联网连接。你使用主动还是被动模式?哪个版本的Indy? – 2015-03-24 23:00:09

+0

我不确定哪些超时没有刷新我的FTP知识,我放弃了使用FTP不稳定(用于程序使用)并在很久以前转移到HTTP。但是你有一个超时的地方。如果不是,那么它在服务器端一定是个问题。 – 2015-03-24 23:05:12

+0

即使有人能够在没有看到完整设置的情况下回答,根据Indy版本和FTP模式的不同,答案可能会有很大差异。你需要包括这些。但我猜如果你没有超时,那么服务器可能会。你尝试过不同的服务器吗? – 2015-03-24 23:08:07

回答

4

FTP协议使用多个TCP/IP连接 - 一个用于主要命令/响应连接,另一个用于数据传输。在数据传输过程中,主要的命令连接处于空闲状态。传输完成后,命令连接会收到响应。

如果您正在通过不支持FTP的路由器/防火墙,那么如果在大量传输过程中闲置太久,命令连接可能会被终止。连接通常不会“优雅地”中止,因此即使操作系统不知道连接也没有了。当TIdFTP然后尝试读取永不到达的传输响应时,它会超时。

要解决该问题,请使用TIdFTP.NATKeepAlive属性在传输期间在命令连接上启用TCP/IP级别保留。将NATKeepAlive.UseKeepAlive设置为True,并将NATKeepAlive.IdleTimeMS(Keepalive开始发送前的空闲超时)和NATKeepAlive.IntervalMS(每个Keepalive之间的间隔)设置为合适的值。

但是请注意,IdleTimeMSIntervalMS目前仅适用于Windows 2000 +,Linux和BSD。其他平台使用OS提供的默认值(通常非常大)。如果您需要自定义这些平台上的值,则可以使用TIdFTP.OnDataChannelCreateTIdFTP.OnDataChannelDestroy事件直接根据需要调用TIdFTP.Socket.Binding.SetSocketOption()

+0

将它们设置为任意y你想要。它们是Indy级超时,而不是TCP级超时。不过,他们希望Indy等待单个字节。我通常会将它们保留为默认值,或者将它们设置为10-15秒以解决网络滞后问题。 – 2015-03-25 14:27:13

+0

看看他们的产品规格。 – 2015-03-25 17:49:54

+0

如果它没有明确声明FTP是受支持的,那么您可能必须推断它是否真的存在,或者只需联系供应商并询问。 – 2015-03-25 18:42:15