我开发了一个使用indy组件从远程服务器下载更新的应用程序。 问题是如果FTP服务器关闭或IP地址不正确,idFTP.connect()花费的时间太长而无法给出结果(连接失败)。
加速连接答案的最佳方法是什么,或者在连接到idFTP之前检查IP地址是什么。
提前致谢。
答案 0 :(得分:2)
您应该设置ReadTimeout属性,默认情况下设置为一分钟。
答案 1 :(得分:2)
默认情况下,只要操作系统报告连接是否成功,Indy客户端就会等待。是的,这可能需要很长时间,如果操作系统必须使用DNS查找主机名,进行网络检查,处理网络延迟等。如果您不想等待那么久,可以使用{{1} Indy 9及更早版本中Timeout
的参数,或Indy 10中的Connect()
属性,以减少等待的时间。 HOWEVER ,仅在确定服务器IP后才适用于实际的套接字连接尝试。如果将ConnectTimeout
属性设置为非IP主机名,则Indy要求操作系统执行DNS查找以获取主机名的IP,并且Host
中没有可用的逻辑来控制所需的时间做那个查找。如果您需要那么多控件,请使用Connect()
手动获取IP,然后在调用TIdDNSResolver
之前将其分配给Host
属性。
答案 2 :(得分:1)
嗯,本机connect()API超时因设计而异常冗长(以适应调制解调器等高延迟链接)。人为地缩短超时可能会导致过早的故障通知,(尽管许多开发人员从未见过调制解调器,但今天的问题并不是那么多:)。
FTP是一种相当复杂的传输,需要两个TCP连接,也许还有一个DNS查找 - 其中任何一个都可能产生长连接延迟。 TidFTP有一个继承的'ReadTimeout'属性和一个带超时参数的connect()重载,但我不确定它们的效果如何。
从历史上看,我总是使用TTimer或类似程序自行计时这些操作 - 如果FTP线程没有用合适的信号响应,(例如,TThread.Sychronize或用户定义的Windows消息SendMessage()'d GUI),及时采取'FTP失败'动作,并在FTP线程中设置一个标志,告诉它忽略任何回复并自行终止。不要使用PostMessage - 如果你这样做的话,有一个小窗口的时间,在TTimer开火的时候,一个已发布的响应排队等候 - 比赛。
哦 - 如果你只是将TidFTP拼接到表单上,(或在TForm.FormCreate中创建一个),并尝试从主GUI线程运行它(使用或不使用TidAntiFreeze),停止执行并断开FTP。