代码之家  ›  专栏  ›  技术社区  ›  Mick

如何使用Indy的IDFTP发送TMemoryStream?

  •  0
  • Mick  · 技术社区  · 16 年前

    我使用的是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,并显示消息“范围检查错误”。

    为了理解这个错误,我在谷歌上花了不少时间,但现在我不知所措。我也只看过一部 example of how to perform a TFTP PUT 使用Indy组件。

    有什么想法吗?

    如果我稍微跟踪一下错误,就会发现错误是从第272行的“idftp.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 回复  |  直到 16 年前
        1
  •  1
  •   Remy Lebeau    16 年前

    D2010附带的Indy 10版本不是可用的最新Indy 10版本。您引用的被破坏的印地代码在当前版本中不再存在。TidFTP在不久前被重新编写以修复许多问题(不过当时我忘了签入它)。我现在已经这样做了)。请从Indy的SVN服务器或Fulgan mirror下载最新的Indy 10快照(您需要等待一天才能赶上)。下载链接可在Indy的网站上找到。

        2
  •  3
  •   Rob Kennedy    16 年前

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

    沟 TIdTrivialFTP TIdFTP .

        3
  •  1
  •   Ken White    16 年前

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

    • 在具有IDFTP1.Name的行上设置断点。
    • 点击F9运行你的应用程序。执行任何触发代码的操作来FTP文件。
    • 当IDE停在断点上时,按F8逐行遍历代码。
    • 注意您点击F8并触发异常的那一行。这就是问题所在。

    由于只有两行会触发范围检查错误(分配端口和ReceiveTimeout的那两行),因此找出哪一行是罪魁祸首应该是+琐碎+(双关语)。我怀疑是端口设置的问题。

        4
  •  1
  •   Warren P    16 年前

    我的答案是;Indy很烂,抛弃它,使用Francois Piette的ICS组件。

    W