加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 使用IdTCPClient和IdTCPServer发送和接收TMemoryStrea

发布时间:2020-12-15 09:36:28 所属栏目:大数据 来源:网络整理
导读:我在XE2中找到了Remy Lebeau的IdTCP组件聊天演示,我想稍微玩一下. (可以找到 here)我想使用这些组件发送图片,最好的方法似乎是使用TMemoryStream.如果我发送字符串,连接工作正常,字符串传输成功,但是当我将其更改为流时,它不起作用.这是代码: 服务器 proced
我在XE2中找到了Remy Lebeau的IdTCP组件聊天演示,我想稍微玩一下. (可以找到 here)我想使用这些组件发送图片,最好的方法似乎是使用TMemoryStream.如果我发送字符串,连接工作正常,字符串传输成功,但是当我将其更改为流时,它不起作用.这是代码:

服务器

procedure TMainForm.IdTCPServerExecute(AContext: TIdContext);
var rcvdMsg: string;
  ms:TMemoryStream;
begin
// This commented code is working,it receives and sends strings.
//  rcvdMsg:=AContext.Connection.IOHandler.ReadLn;
//  LogMessage('<ServerExec> '+rcvdMsg);
//
//  TResponseSync.SendResponse(AContext,rcvdMsg);
  try
    ms:=TMemoryStream.Create;
    AContext.Connection.IOHandler.ReadStream(ms);

    ms.SaveToFile('c:networked.bmp');
  except
    LogMessage('Failed to receive',clred);
  end;
end;

客户

procedure TfrmMain.Button1Click(Sender: TObject);
var ms: TMemoryStream;
    bmp: TBitmap;
    pic: TPicture;
    s: string;
begin
  // Again,this code is working for sending strings.
  // s:=edMsg.Text;
  // Client.IOHandler.WriteLn(s);
  ms:=TMemoryStream.Create;

  pic:=TPicture.Create;
  pic.LoadFromFile('c:Back.png');

  bmp:=TBitmap.Create;
  bmp.Width:=pic.Width;
  bmp.Height:=pic.Height;
  bmp.Canvas.Draw(0,pic.Graphic);

  bmp.SaveToStream(ms);
  ms.Position:=0;
  Client.IOHandler.Write(ms);
  ms.Free;
end;

当我尝试从客户端发送流时,没有任何可观察的事件发生(OnExecute中的断点不会触发).但是,在关闭程序时(发送MemoryStream之后),会发生两件事:

>如果首先关闭客户端,那么只有那时才会处理除外部分(日志显示’接收失败’错误.但是,即使我在try-except块的第一行放置一个断点,它也会以某种方式获得跳过,只显示错误).
>如果首先关闭服务器,则IDE不会从调试返回,客户端不会将其状态更改为断开连接(通常在服务器断开连接时),并且在客户端关闭后也会发生访问冲突错误服务器应用程序出现.我想这意味着服务器的一个线程仍在运行并维护连接.但无论我给它多少时间,它都永远不会完成接收MemoryStream的任务.

注意:如果重要,服务器使用IdSchedulerOfThreadDefault和IdAntiFreeze.

由于我找不到任何可靠的改造Indy 10的帮助来源(它似乎都适用于较旧的Indy 10,甚至Indy 9),我希望你能告诉我出了什么问题.谢谢

– 答案 –

服务器

procedure TMainForm.IdTCPServerExecute(AContext: TIdContext);
var size: integer;
    ms:TMemoryStream;
begin
  try
    ms:=TMemoryStream.Create;
    size:=AContext.Connection.IOHandler.ReadLongInt;
    AContext.Connection.IOHandler.ReadStream(ms,size);

    ms.SaveToFile('c:networked.bmp');
  except
    LogMessage('Failed to receive',clred);
  end;
end;

客户

procedure TfrmMain.Button1Click(Sender: TObject);
var ms: TMemoryStream;
    bmp: TBitmap;
    pic: TPicture;
begin
  ms:=TMemoryStream.Create;

  pic:=TPicture.Create;
  pic.LoadFromFile('c:Back.png');

  bmp:=TBitmap.Create;
  bmp.Width:=pic.Width;
  bmp.Height:=pic.Height;
  bmp.Canvas.Draw(0,pic.Graphic);

  bmp.SaveToStream(ms);
  ms.Position:=0;
  Client.IOHandler.Write(ms,True);
  ms.Free;
end;

解决方法

只需使用适当的参数:

.IOHandler.Write(ms,true); //true ... indicates WriteByteCount

.IOHandler.ReadStream(ms,-1); //-1 ... use ByteCount

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读