Исключение Indy TFTP Server EIdTFTPAllocationExceeded

Я получаю исключение EIdTFTPAllocationExceeded при передаче файла от меня (сервер - с использованием компонента Indy TIdTrivialFTPServer) на устройство. Я не могу найти никакой информации о том, что может означать это исключение, за исключением, возможно, проблемы с дисковым пространством на клиенте (я знаю, что это не так, потому что, если я передам файл через другой TFTP-сервер, проблем не будет).

  1. Что такое исключение пытается сказать мне?
  2. Как мне обойти это?
  3. Есть ли код, который мне не хватает?

Мой код TFTP-сервера (всего) для сервера:

__fastcall TTrivialFTPServer::TTrivialFTPServer(TComponent* Owner) : TDataModule(Owner)
{
    root = IncludeTrailingPathDelimiter(GetCurrentDir());
}

// ---------------------------------------------------------------------------
void __fastcall TTrivialFTPServer::tftpReadFile(TObject *Sender, UnicodeString &FileName, const TPeerInfo &PeerInfo, bool &GrantAccess, TStream *&AStream, bool &FreeStreamOnComplete)
{
    FreeStreamOnComplete = true;
    FileName = StringReplace(FileName, "/", "\\", TReplaceFlags() << rfReplaceAll);
    FileName = ExtractFileName(FileName);
    if (FileExists(root + "files\\" + FileName, false))
    {
        AStream = new TFileStream(root + "files\\" + FileName, fmOpenRead | fmShareDenyWrite);
        GrantAccess = true;
    }
    else
    {
        GrantAccess = false;
    }
}

person Brian P.    schedule 09.01.2019    source источник


Ответы (1)


После долгих поисков и головокружений я, наконец, открыл файл IdTrivialFTPServer.pas и обнаружил проблему. Кодекс гласит:

if FBlkCounter = High(UInt16) then begin
    raise EIdTFTPAllocationExceeded.Create('');
end;

Когда я добавил текст в исключение, я получил добавленный текст, поэтому здесь возникает ошибка. Я пытался преобразовать UInt16 в UInt32, но это вызвало гораздо больше проблем, поэтому я хотел посмотреть, что произойдет, если я просто закомментирую проверку и позволю счетчику вернуться к нулю.

Как оказалось, ничего страшного не происходит, и файл передается просто отлично!

person Brian P.    schedule 10.01.2019
comment
16-битный счетчик блоков данных начинается с 1. 0 используется только при ответе на запрос о передаче. Протокол TFTP не определяет, как 16-битный счетчик должен сбрасываться, если вообще должен, на 0 или 1 после отправки 65535 пакетов данных. Размер блока по умолчанию для каждого пакета данных составляет 512 байт, поэтому максимальный размер файла по умолчанию составляет 32 МБ. Для больших файлов клиент может запросить больший размер блока при запросе на передачу файла, что эффективно увеличивает максимальный размер файла до 91 МБ. Это единственный официальный вариант. Все, что сверх этого, является нестандартным поведением. См. compuphase.com/tftp.htm. - person Remy Lebeau; 11.01.2019
comment
Я могу решить добавить настраиваемые параметры к компонентам TFTP для управления поведением переноса. См. github.com/IndySockets/Indy/issues/242. - person Remy Lebeau; 11.01.2019
comment
Интересно читать оба. Спасибо. В статье compuphase рассказывается о методе ролловера, а также о других. По-видимому, это то, что было реализовано на одном из коммерческих TFTP-серверов, которые я использовал для тестирования, а также то, что я непреднамеренно реализовал в коде. Я думаю, что лучшим выбором будет предоставление опции в свойствах, а также некоторая документация о том, что это такое и зачем это нужно (ссылки, приведенные выше, были очень полезны для меня). - person Brian P.; 11.01.2019