我想从FTP下载文件。如果文件很小(通常低于1000MB),它可以工作。但是,如果文件很大,我会得到一个EIdReadTimeout。为什么?我应该保持连接活着吗?据我所知,阅读数据有自己的频道,所以我不必保持连接活着。
奇怪的是,异常出现在Get的结尾(Get成功下载整个文件之后):FTP.Get(Name,TempGzFile,TRUE,FALSE)!!!!
文档:
TIdFTP.ReadTimeout - 等待FTP协议响应的毫秒数。
TIdFTP.TransferTimeout - FTP数据通道上读取操作的超时值 客户端。
默认情况下,ReadTimeout设置为60秒,TransferTimeout设置为10秒。
我使用Delphi XE7(我想使用Indy 10)。我的IdFTP的被动属性设置为false。
答案 0 :(得分:5)
FTP协议使用多个TCP / IP连接 - 一个用于主命令/响应连接,另一个用于数据传输。正在进行数据传输时,主命令连接处于空闲状态。传输完成后,命令连接会收到响应。
如果您正在通过不支持FTP的路由器/防火墙,如果在大型传输过程中空闲时间过长,则命令连接可能会被终止。连接通常不会“优雅”地被杀死,因此即使操作系统也不知道连接已经消失。当TIdFTP
然后尝试读取永不到达的转移响应时,它会超时。
要考虑到这一点,请使用TIdFTP.NATKeepAlive
属性在传输期间启用命令连接上的TCP / IP级别保持活动。将NATKeepAlive.UseKeepAlive
设置为True,并将NATKeepAlive.IdleTimeMS
(Keepalive开始发送前的空闲超时)和NATKeepAlive.IntervalMS
(每个keepalive之间的间隔)设置为合适的值。
但请注意,IdleTimeMS
和IntervalMS
目前仅适用于Windows 2000 +,Linux和BSD。其他平台使用操作系统提供的默认值(通常非常大)。如果您需要自定义这些平台上的值,可以使用TIdFTP.OnDataChannelCreate
和TIdFTP.OnDataChannelDestroy
事件直接根据需要调用TIdFTP.Socket.Binding.SetSocketOption()
。