我在XE2中发现了Remy Lebeau的IdTCP组件的聊天演示,我想稍微玩一下。 (可以找到here)我想用这些组件发送图片,最好的方法似乎是使用TMemoryStream。如果我发送字符串,连接工作正常,字符串传输成功,但是当我将其更改为Stream时,它不起作用。下面是代码:使用IdTCPClient和IdTCPServer发送和接收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,0,pic.Graphic);
bmp.SaveToStream(ms);
ms.Position:=0;
Client.IOHandler.Write(ms);
ms.Free;
end;
当我尝试发送来自客户端的数据流,没有任何可观察到的情况(断点在OnExecute没有按” t火)。然而,在关闭程序时(发送的MemoryStream后),两件事情发生:
- 如果客户是第一次关闭,最后才在
except
部分得到处理(日志显示“无法接受”的错误。但是,即使我在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;
CLIENT
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;
先发流的大小,这样服务器确切地知道它需要读多少字节。 – whosrdaddy