0

我正在使用它附带的 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,并带有消息“范围检查错误”。

我一直在做很多谷歌搜索来理解这个错误,但我目前不知所措。我也只看到了一个如何使用 Indy 组件执行 TFTP PUT 的示例。

有任何想法吗?

更新: 如果我稍微追踪一下错误,我发现错误是从第 272 行的“IdTrivialFTP.pas”中抛出的:

    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 }
4

4 回答 4

3

很好地确定了异常的来源。当您遇到异常时,这应该始终是您做的第一件事。

您使用的 Indy 代码已损坏。即使没有范围检查错误,它仍然不会从源流中发送任何数据。您可以自己看到读取流内容的行已被注释掉。它仍然在今天的开发快照中被注释掉,看起来已经有两年多没有人处理这个文件了。事实上,自从文件在修订版 7 中添加到 Subversion 存储库后,该行就被注释掉了。

改用TIdTrivialFTP成熟的 FTP 客户端试试运气,TIdFTP.

于 2009-12-29T22:20:21.120 回答
1

你可以自己很容易地解决这个问题:

  • 在 IdTrivialFTP1.Name 行上设置断点。
  • 按 F9 运行您的应用程序。执行任何触发代码以 FTP 文件传输的操作。
  • 当 IDE 在断点处停止时,按 F8 以逐行执行代码。
  • 请注意您按 F8 并触发异常的行。这就是问题所在。

由于您只有两行应该触发范围检查错误(分配 Port 和 ReceiveTimeout 的行),因此找出罪魁祸首应该是 +trivial+(双关语)。我怀疑这是端口设置。

另外,不要忘记 Indy 带有完整的源代码。如果您将项目的编译器选项设置为使用调试 DCU,您也可以对此进行跟踪。(项目|选项|编译器)

于 2009-12-29T22:00:48.690 回答
1

我的回答是;Indy 很烂,放弃它并使用 Francois Piette 的 ICS 组件。

W

于 2009-12-30T14:05:05.227 回答
1

D2010 随附的 Indy 10 版本不是可用的最新 Indy 10 修订版。您引用的被破坏的 Indy 代码在当前版本中不再存在。TIdTrivialFTP 不久前被重写以解决很多问题(不过,我当时忘记检查它。我现在已经这样做了)。请从 Indy 的 SVN 服务器或 Fulgan 镜像下载最新的 Indy 10 快照(您必须等待一天才能赶上)。下载链接可在 Indy 的网站上找到。

于 2010-01-04T22:45:05.170 回答