2015-03-24 2 views
0

Я хочу загрузить файл с FTP. Если файл небольшой (обычно менее 1000 МБ), он работает. Однако, если файл большой, я получаю 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). Свойству Passive для моего IdFTP установлено значение false.

+0

Снимите тайм-аут или увеличьте его. В любом случае загрузка большого файла или неизвестного размера файла не должна иметь тайм-аута вообще или, возможно, должна быть установлена ​​на большое время. Представьте, что кто-то использует очень медленное подключение к Интернету. Вы используете активный или пассивный режим? И какая версия Indy? –

+0

Я не уверен, какой тайм-аут, не читая мои знания FTP, я отказался от использования FTP для того, чтобы быть нестабильным (для использования программы) и перешел на HTTP давным-давно. Но где-то у вас есть тайм-аут. Если нет, то это должно быть проблемой на стороне сервера. –

+0

Даже если кто-то может ответить, не видя вашей полной настройки, ответ может существенно отличаться в зависимости от версии Indy и режима FTP. Вы должны включить их. Но я предполагаю, что если у вас нет тайм-аута, возможно, сервер. Вы пробовали на разных серверах? –

ответ

4

Протокол FTP использует несколько соединений TCP/IP - один для основного соединения команды/ответа и отдельные соединения для передачи данных. Пока выполняется передача данных, основное командное соединение находится в режиме ожидания. Как только передача завершена, командное соединение получает ответ.

Если вы проходите через маршрутизатор/брандмауэр, который не поддерживает FTP, соединение с командой, вероятно, будет убито, если он слишком долго простаивает во время большой передачи. Соединение обычно не убивается «изящно», поэтому даже ОС не знает, что соединение ушло. Когда TIdFTP затем пытается прочитать ответ на передачу, который никогда не прибывает, время истекает.

Чтобы исправить это, используйте свойство TIdFTP.NATKeepAlive, чтобы включить поддерживающие каналы уровня TCP/IP в командном соединении во время передачи. Установите NATKeepAlive.UseKeepAlive в значение True и установите NATKeepAlive.IdleTimeMS (время ожидания простоя до начала отправки) и NATKeepAlive.IntervalMS (интервал между каждым keepalive) до подходящих значений.

Обратите внимание, что IdleTimeMS и IntervalMS предназначены только для Windows 2000+, Linux и BSD. На других платформах используются значения по умолчанию, предоставляемые ОС (которые, как правило, очень большие). Если вам нужно настроить значения на этих платформах, вы можете использовать события TIdFTP.OnDataChannelCreate и TIdFTP.OnDataChannelDestroy, чтобы позвонить по телефону TIdFTP.Socket.Binding.SetSocketOption() непосредственно по мере необходимости.

+0

Установите их на любой y ou хотите. Это тайм-ауты уровня Indy, а не тайм-ауты на уровне TCP. Они, однако, долго вы хотите Indy ждать отдельных байтов. Обычно я оставляю их по умолчанию или устанавливаю их на 10-15 + секунд, чтобы учесть отставание в сети. –

+0

Посмотрите на характеристики своих продуктов. –

+0

Если в нем явно не указано, что FTP поддерживается, тогда вам, вероятно, придется определить, действительно ли это или нет, или просто связаться с продавцом и спросить. –

 Смежные вопросы

  • Нет связанных вопросов^_^