Хобрук: Ваш путь к мастерству в программировании

Как отправить TMemoryStream с помощью Indy IdTrivialFTP?

Я использую Delphi 2010 и Indy 10, которые поставляются с ним. MemStream представляет собой TMemoryStream и содержит файл, загруженный с веб-сайта.

IdTrivialFTP1 := TIdTrivialFTP.Create(nil);
try
  IdTrivialFtp1.Name := 'IdTrivialFTP1';
  IdTrivialFTP1.Host := 'my-tftp-server-name.contoso.com';
  IdTrivialFTP1.Port := 69;
  IdTrivialFTP1.ReceiveTimeout := 4000;

  MemStream.Position := 0;
  IdTrivialFTP1.Put(MemStream, sFileName);
finally
  FreeAndNil(IdTrivialFTP1);
end;

Всякий раз, когда я запускаю этот код, я получаю сообщение об ошибке:

Проект TestProject.exe вызвал класс исключения ERangeError с сообщением «Ошибка проверки диапазона».

Я немного погуглил, чтобы понять эту ошибку, но сейчас я в недоумении. Я также видел только 1 пример выполнения TFTP PUT с использованием компонентов Indy. .

Любые идеи?

ОБНОВЛЕНИЕ: если немного проследить ошибку, я обнаружу, что ошибка возникает из "IdTrivialFTP.pas" в строке 272:

    CurrentDataBlk := WordToStr(GStack.HostToNetwork(Word(TFTP_DATA)))
+ WordToStr(GStack.HostToNetwork(BlockCtr));

Для ясности вот контекст этого кода:

if BlockCtr > PrevBlockCtr then
  begin
    DataLen := IndyMin(BufferSize - hdrsize, SourceStream.Size - SourceStream.Position);
    SetLength(CurrentDataBlk, DataLen + hdrsize);
    CurrentDataBlk := WordToStr(GStack.HostToNetwork(Word(TFTP_DATA))) + WordToStr(GStack.HostToNetwork(BlockCtr));
    SetLength(CurrentDataBlk, DataLen + hdrsize);
    //SourceStream.ReadBuffer(CurrentDataBlk[hdrsize+1], DataLen);
    DoWork(wmWrite, DataLen);
    TerminateTransfer := DataLen < BufferSize - hdrsize;
    PrevBlockCtr := BlockCtr;
  end;
  Send(FPeerIP, FPeerPort, CurrentDataBlk);
until False;  { repeat }
29.12.2009

Ответы:


1

Версия Indy 10, поставляемая с D2010, НЕ является последней доступной версией Indy 10. Код Indy, который вы назвали сломанным, больше не существует в текущей версии. TIdTrivialFTP был переписан некоторое время назад, чтобы исправить множество проблем (однако я забыл проверить его в то время. Я сделал это сейчас). Пожалуйста, загрузите последний снимок Indy 10 с сервера Indy SVN или зеркала Fulgan (вам придется подождать день, пока он наверстает упущенное). Ссылки для скачивания доступны на веб-сайте Indy.

04.01.2010
  • У меня есть IdTrivialFTP.pas версии 3979 с сайта svn.atozed.com, а строка SourceStream.ReadBuffer все еще закомментирована. 05.01.2010
  • Проверьте файл IdTrivialFTP.pas, который находится в папке \Indy10\branches\Tiburon\Lib\Protocols. 05.01.2010
  • Кроме того, я только что понял, что проверил ревизию 3980, так что может быть причина, по которой вы ее не видели. 05.01.2010
  • О да. Теперь я вижу, что разработка ведется в ветви Tiburon, а не в магистрали. Как долго это будет исправлено, Реми? Tiburon было кодовым названием Delphi 2009, не так ли? Я бы никогда не подумал получить последнюю версию из ветки, названной в честь устаревшего кодового имени. 05.01.2010
  • Да, Tiburon было кодовым названием Delphi 2009. Именно тогда мы начали интеграцию Indy с Unicode. Он еще не закончен. Нет ETA, когда ветка Tiburon будет объединена с Trunk. Использование Branch вместо Trunk для получения последнего кода указано в инструкциях по загрузке на веб-сайте Indy. 06.01.2010

  • 2

    Хорошая работа по определению источника исключения. Это всегда должно быть первым, что вы делаете, когда сталкиваетесь с исключением.

    Используемый вами код Indy не работает. Даже если бы не было ошибки проверки диапазона, он все равно не отправил бы никаких данных из исходного потока. Вы сами видите, что строка, читающая содержимое потока, закомментирована. Он все еще закомментирован в сегодняшнем снимке разработки, и похоже, что прошло более двух лет с тех пор, как кто-либо работал над этим файлом. На самом деле эта строка была закомментирована с тех пор, как файл был добавлен в репозиторий Subversion в версии 7.

    Откажитесь от TIdTrivialFTP и попытайте счастья с полноценным FTP-клиентом, TIdFTP.

    29.12.2009
  • Некоторые системы, такие как телефоны VOIP, используют TFTP, а не FTP. 06.01.2010

  • 3

    Вы можете решить это довольно легко самостоятельно:

    • Установите точку останова на строке с IdTrivialFTP1.Name.
    • Нажмите F9, чтобы запустить приложение. Делайте все, что запускает код для FTP-файла.
    • Когда среда IDE остановится в точке останова, нажмите F8, чтобы выполнить код построчно.
    • Обратите внимание на строку, в которой вы нажимаете F8, и возникает исключение. Это проблемная линия.

    Поскольку у вас есть только две строки, которые должны вызвать ошибку проверки диапазона (те, которые назначают порт и ReceiveTimeout), выяснить, какая из них является виновником, должно быть + тривиально + (каламбур). Я подозреваю, что это настройка порта.

    Кроме того, не забывайте, что Indy поставляется с полным исходным кодом. Вы также можете проследить это, если вы установите параметры компилятора вашего проекта для использования отладочных DCU. (Проект|Параметры|Компилятор)

    29.12.2009
  • Проблема в исходном коде Indy, но, честно говоря, я не знаю, как это исправить. Я обновлю свой комментарий с подробностями. 30.12.2009

  • 4

    Мой ответ был бы; Indy отстой, выбросьте его и используйте компоненты ICS Франсуа Пиетта.

    W

    30.12.2009
    Новые материалы

    Понимание структуры каталогов Linux
    Структура каталогов Linux — это иерархическая организация файлов и каталогов в системе Linux. Понимание этой структуры важно для всех, кто хочет использовать Linux в качестве основной..

    Введение в SQLite3 в Python
    SQLite3 — это популярная и часто используемая программная библиотека для управления реляционными базами данных. Она портативна, быстра и проста в использовании, что делает ее отличным выбором..

    Как создать ORM в Node.js
    Что такое ОРМ? Проще говоря, система ORM — это метод, в котором вы используете объектно-ориентированную парадигму для создания сопоставления между приложением и базой данных для выполнения..

    Руководство для начинающих по обработке естественного языка .
    Обработка естественного языка — захватывающая и быстро развивающаяся область, которую можно охарактеризовать как сочетание лингвистики, информатики и искусственного интеллекта. Это помогает..

    Защитите свое приложение NodeJS с помощью веб-токенов JSON (JWT): руководство по аутентификации на основе токенов
    В современном мире веб-приложений безопасность важнее, чем когда-либо. Одним из наиболее важных аспектов защиты веб-приложений является аутентификация пользователей. Аутентификация на основе..

    Вводное руководство по аннотациям @PreAuthorize и @PostAuthorize в Spring Security
    Введение Spring Security — это мощная и настраиваемая среда аутентификации и контроля доступа для приложений Java, особенно тех, которые созданы с использованием среды Spring. Этот пост..

    От стартапов к успеху в индустрии наук о данных: 5 важных инструментов
    Постоянно растущие объемы данных сегодня играют решающую роль для каждой компании, которая хочет оставаться на вершине. Это означает использование технологий искусственного интеллекта ,..