gpt4 book ai didi

delphi - 使用 IdTCPClient 和 IdTCPServer 发送和接收 TMemoryStream

转载 作者:可可西里 更新时间:2023-11-01 02:32:24 27 4
gpt4 key购买 nike

我在 XE2 中找到了 Remy Lebeau 的 IdTCP 组件的聊天演示,我想玩一下。 (可以找到 here )我想使用这些组件发送图片,最好的方法似乎是使用 TMemoryStream。如果我发送字符串,连接正常,字符串传输成功,但是当我将其更改为 Stream 时,它不起作用。这是代码:

服务器

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,0,pic.Graphic);

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

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

  • 如果客户端先关闭,那么只有 except 部分才会被处理(日志显示“接收失败”错误。但是,即使我在第一行放置断点try-except block ,它会以某种方式被跳过,只显示错误)。
  • 如果先关闭服务器,IDE 不会从调试 改回状态,客户端不会将其状态更改为断开连接(通常在服务器关闭时会这样)断开连接)并且在客户端也关闭后,会出现来自服务器应用程序的访问冲突错误。我想这意味着服务器的一个线程仍在运行并保持连接。但无论我给它多少时间,它都无法完成接收 MemoryStream 的任务。

注意:如果重要的话,服务器使用 IdSchedulerOfThreadDefaultIdAntiFreeze

由于我找不到任何可靠的关于改进后的 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,0,pic.Graphic);

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

最佳答案

只需使用适当的参数:

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

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

关于delphi - 使用 IdTCPClient 和 IdTCPServer 发送和接收 TMemoryStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12159868/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com