消息"读取超时"[Indy-IdFTP]的异常类EIdReadTimeout

WeG*_*ars 0 delphi ftp indy indy10

我想从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.

Rem*_*eau 5

FTP协议使用多个TCP/IP连接 - 一个用于主命令/响应连接,另一个用于数据传输.正在进行数据传输时,主命令连接处于空闲状态.传输完成后,命令连接会收到响应.

如果您正在通过不支持FTP的路由器/防火墙,如果在大型传输过程中空闲时间过长,则命令连接可能会被终止.连接通常不会"优雅"地被杀死,因此即使操作系统也不知道连接已经消失.TIdFTP然后当尝试读取永远不会到达的传输响应时,它会超时.

要考虑到这一点,请使用该TIdFTP.NATKeepAlive属性在传输期间启用命令连接上的TCP/IP级别保持活动.设置NATKeepAlive.UseKeepAlive为True,并设置NATKeepAlive.IdleTimeMS(keepalives开始发送前的空闲超时)和NATKeepAlive.IntervalMS(每个keepalive之间的间隔)为适当的值.

但是请注意,这IdleTimeMSIntervalMS为Windows 2000 +,Linux和BSD此时只实现.其他平台使用操作系统提供的默认值(通常非常大).如果需要在这些平台上自定义值,可以根据需要使用TIdFTP.OnDataChannelCreateTIdFTP.OnDataChannelDestroy事件TIdFTP.Socket.Binding.SetSocketOption()直接调用.