【问题标题】:Udp image streaming, delphi indy10udp图像流,delphi indy10
【发布时间】:2013-07-02 15:42:27
【问题描述】:

我正在使用带有 indy10 组件的 delphi xe4,我想将图像从 Tidudpclient 发送到 Tidudpserver。我已经使用 tcp 组件完成了此操作,但相同的代码不适用于 udp。我怎么能这样做? 提前致谢!

Timage(客户端)--->streamUDP-->Timage(服务器)

客户端--------------------------------------------- -- 发送图片

var
    pic: tbitmap;
       Strm : TMemoryStream;
        img2:Timage;

    buffer:TIdBytes;
    begin

        try
          img2:=Timage.Create(nil);
          pic:=Tbitmap.Create;
          Takekpic(pic);     
          BMPtoJPG(pic,img2);
          Strm := TMemoryStream.Create;
          img2.Picture.bitmap.SaveToStream(strm);
          Strm.Position:=0;
          ReadTIdBytesFromStream(Strm,buffer,SizeOf(Strm),0);
          IdTrivialFTPServer1.SendBuffer('192.168.17.128',1234,buffer);
        finally
             strm.Free;
          end; 
    end;

服务器端------------------------------ ------- 阅读图片

procedure TForm6.IdTrivialFTP1UDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
    var
Strm : TMemoryStream;
Jpg: TJpegImage;

begin
      Strm := TMemoryStream.Create;
      try    

         WriteTIdBytesToStream(Strm,AData,SizeOf(AData),0);
         strm.Position:=0;
         Jpg := TJpegImage.Create;
         jpg.LoadFromStream(Strm);  <---- error while reading (JPEG Error #53)
         img1.Picture.assign(jpg);
      finally
         strm.Free;
         Jpg.Free;
      end;
end;

这段代码有什么问题?

【问题讨论】:

  • codeforge.com/dlpre/139356 在这个项目中你得到了你需要的一切。
  • 您如何确保您通过 UDP 发送的所有数据都完好无损、完整且按正确顺序接收?
  • @FlashThunder 我无法下载此项目...
  • @Arioch'The 查看 Remy Lebeau 的答案
  • “阅读时出错”很好......我知道在哪里聘请间谍来监视你并告诉我错误是什么。真的,如果你一直隐瞒事实信息,你如何让任何人了解你的情况? catb.org/esr/faqs/smart-questions.html#beprecise

标签: delphi tcp udp indy


【解决方案1】:

TIdUDPClientTIdUDPServer 不支持发送/接收TStream 数据。您可以将图像数据保存到TStream,但您必须使用TIdBytes 块发送/接收它。

或者,改用TIdTrivialFTPTIdTrivialFTPServer,它们实现了基于UDP 的文件传输协议TFTP。他们使用TStream 对象进行操作

更新:例如:

客户:

var
  bmp: TBitmap;
  jpg: TJPEGImage;
  Strm : TMemoryStream;
begin
  Strm := TMemoryStream.Create;
  try
    jpg := TJPEGImage.Create;
    try
      bmp := TBitmap.Create;
      try 
        Takekpic(bmp);     
        jpg.Assign(bmp);
      finally
        bmp.Free;
      end;
      jpg.SaveToStream(Strm);
    finally
      jpg.Free;
    end;
    Strm.Position := 0;
    {
    These can be assigned ahead of time...
    IdTrivialFTP1.Host := '192.168.17.128';
    IdTrivialFTP1.Port := 1234;
    }
    IdTrivialFTP1.Put(Strm, 'image.jpg');
  finally
    Strm.Free;
  end; 
end;

服务器:

procedure TForm6.IdTrivialFTPServer1WriteFile(Sender: TObject; var FileName: String; const PeerInfo: TPeerInfo; var GrantAccess: Boolean; var AStream: TStream; var FreeStreamOnComplete: Boolean) of object;
begin
  if FileName = 'image.jpg' then
  begin
    GrantAccess := True;
    AStream := TMemoryStream.Create;
    FreeStreamOnComplete := True;
  end else
    GrantAccess := False;
end;

{
If you set TIdTrivialFTPServer.ThreadedEvent to False, this event handler
runs in the context of the main thread, so the UI can be accessed safely.
If you set IdTrivialFTPServer.ThreadedEvent to True, this event handler
runs in the context of a worker thread, so you will have to manually
synchronize with the main thread when updating the UI...
}
procedure TForm6.IdTrivialFTPServer1TransferComplete(Sender: TObject; const Success: Boolean; const PeerInfo: TPeerInfo; var AStream: TStream; const WriteOperation: Boolean);
var
  jpg: TJPEGImage;
begin
  if WriteOperation and Success then
  begin
    jpg := TJPEGImage.Create;
    try
      AStream.Position := 0;
      jpg.LoadFromStream(AStream);
      img1.Picture.Assign(jpg);
    finally
      jpg.Free;
    end;
  end;
end;

【讨论】:

  • 我想创建一个图像流,我认为这不是使用 ftp 的最佳方式
  • @user1931849 TrivialFTP 与 FTP 没有任何共同点——就像 JavaScript 和 Java 没有共同点
  • @user1931849:FTP 和 TFTP 不是一回事。 FTP 是基于 TCP 的,是一个完整的文件管理协议,而不仅仅是用于传输文件。 TFTP 是基于 UDP 的,其唯一目的是传输数据,仅此而已。
  • @RemyLebeau 如何将我的图像数据保存到 TStream 并使用 TIdBytes 块发送/接收它?或者我怎么能用微不足道的 ftp 做到这一点?
  • @user1931849:您将错误的参数传递给ReadTIdBytesFromStream()WriteTIdBytesToStream()(使用Strm.SizeLength(AData) 而不是SizeOf()),发送端的转换次数太多(bmp 到 jpg 到 bmp 到流式传输到字节),你完全滥用了TIdFTPTrivialServer。在发送端使用TIdTrivialFTP.Put() 方法,在接收端使用TIdTrivialFTPServer.OnWriteFile 事件。
猜你喜欢
  • 1970-01-01
  • 2018-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多