如何使用Indy的IdTrivialFTP发送TMemoryStream?

时间:2009-12-29 21:39:00

标签: delphi ftp indy

我正在使用随附的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;

每当我运行此代码时,都会收到错误:

  

Project TestProject.exe引发了异常类ERangeError,并显示消息“Range check error”。

我一直在做一些google-ing来理解这个错误,但我现在不知所措。我还看到只有1 example of how to perform a TFTP PUT使用Indy组件。

有什么想法吗?

更新 如果我稍微查看错误,我发现错误是从第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 个答案:

答案 0 :(得分:3)

确定异常来源的好工作。这应该是你遇到异常时首先要做的事情。

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

抛弃TIdTrivialFTP并尝试使用成熟的FTP客户端,TIdFTP

答案 1 :(得分:1)

您可以自己轻松解决此问题:

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

由于你只有两行应该触发范围检查错误(分配Port和ReceiveTimeout的那些),找出哪一个是罪魁祸首应该是+平凡+(双关语)。我怀疑这是端口设置。

另外,不要忘记Indy附带完整的源代码。如果将项目的编译器选项设置为使用调试DCU,也可以跟踪到这一点。 (项目|选项|编译器)

答案 2 :(得分:1)

我的回答是; Indy糟透了,抛弃它并使用Francois Piette的ICS组件。

w ^

答案 3 :(得分:1)

D2010附带的Indy 10版本并非最新的Indy 10版本。您引用为已损坏的Indy代码在当前版本中不再存在。 TIdTrivialFTP在前一段时间被重新编写以修复很多问题(但我当时忘了检查它。我现在已经这样做了)。请从Indy的SVN服务器或Fulgan镜像下载最新的Indy 10快照(您将需要等待一天才能赶上它)。下载链接可在Indy的网站上找到。