如何使用Indy的IdTrivialFTP发送TMemoryStream?

问题描述:

我正在使用Delphi 2010和Indy 10。 MemStream是一个TMemoryStream,它包含从网站下载的文件。如何使用Indy的IdTrivialFTP发送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 raised exception class ERangeError with message 'Range check error'.

我已经做了相当多的谷歌-ING的理解这个错误,但目前处于亏损状态,我。我也见过使用Indy组件的只有1 example of how to perform a TFTP PUT

任何想法?

UPDATE: 如果我跟踪到错误了一下,我发现错误正在从抛出“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 } 

印10与D2010一同发布的版本是不是最新的Indy 10版本可用。您所引用的Indy代码已被破坏,并不存在于当前版本中。 TIdTrivialFTP在前一段时间被重写,以解决很多问题(但我当时忘了检查它,现在我已经这样做了)。请从Indy的SVN服务器或Fulgan镜像下载最新的Indy 10快照(您需要等待一天才能赶上)。下载链接可在Indy的网站上找到。

+0

我在svn.atozed.com的修订版3979中有IdTrivialFTP.pas,并且'SourceStream.ReadBuffer'这一行仍然被注释掉。 – 2010-01-05 03:50:51

+0

检查位于\ Indy10 \ branches \ Tiburon \ Lib \ Protocols的IdTrivialFTP.pas。 – Mick 2010-01-05 14:38:18

+0

此外,我刚刚意识到我检查了修订版3980,所以这可能是您没有看到它的原因。 – Mick 2010-01-05 14:56:49

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

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

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

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

+0

问题出在Indy源代码,但说实话,我不知道如何解决它。我会更新我的评论与细节。 – Mick 2009-12-29 22:07:45

确定异常源的好工作。这应该总是你在遇到异常时做的第一件事。

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

沟渠TIdTrivialFTP而且尝试用完全成熟的FTP客户端来代替TIdFTP

+0

某些系统(如VOIP电话)使用TFTP而不使用FTP。 – 2010-01-06 20:35:33

我的答案应该是; Indy糟透了,使用Francois Piette的ICS组件。

W¯¯

+0

我会检查出来。 – Mick 2009-12-30 15:41:39