gpt4 book ai didi

delphi - IndyTCP delphi对象数组交换

转载 作者:可可西里 更新时间:2023-11-01 02:55:46 25 4
gpt4 key购买 nike

对不起,我知道我问了太多问题,但明天(实际上是今天,因为在我的国家现在是凌晨 2:00)我需要向我的老师展示我开始制作的东西等。因此,正如我在之前的问题中所问的那样,我需要从服务器向客户端发送一些数据。但是在 memo1.Lines.Add(IntToStr(arrOf[1]));

之后服务器的备忘录字段中没有任何内容

我试着在客户端发送它

procedure TForm1.btnTestClick(Sender: TObject);
var
msRecInfo: TMemoryStream;
arrOf: array of integer; i:integer;
begin
setLength(arrOf, 11);
for i := 0 to 10 do
arrOf[i]:=random(100);

msRecInfo:= TMemoryStream.Create;

try
msRecInfo.Write(arrOf, SizeOf(arrOf));
idTCPClient1.IOHandler.Write(msRecInfo);
finally
msRecInfo.Free;
end;

end;

在服务器上

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
msRecInfo: TMemoryStream;
arrOf: array of Integer; i:integer;
begin
msRecInfo:= TMemoryStream.Create;
try
AContext.Connection.IOHandler.ReadStream(msRecInfo, -1, False);
SetLength(arrOf,11);
msRecInfo.Position := 0;
msRecInfo.Read(arrOf, SizeOf(arrof));
finally
memo1.Lines.Add(IntToStr(arrOf[1]));
msRecInfo.Free;
end;
end;

你能帮我解决这个问题并找到一些如何发送不同类型/类数组的例子吗?

最佳答案

正如 Rufo 已经解释过的,您没有正确地将数组写入 TMemoryStream 以及从中读取数组。

更糟糕的是,您也没有通过套接字正确发送 TMemoryStreamTIdIOHandler.Write(TStream)TIdIOHandler.ReadStream() 的默认参数彼此不兼容。默认情况下,Write(TStream)发送TStream.Size值。但是,ReadStream() 的默认参数(与您显式传入的值相同)告诉它读取前几个字节并将它们解释为 Size ,在这个例子中这是非常错误的。

试试这个:

procedure TForm1.btnTestClick(Sender: TObject);
var
msRecInfo: TMemoryStream;
arrOf: Array of Integer;
i: Integer;
begin
SetLength(arrOf, 11);
for i := Low(arrOf) to High(arrOf) do
arrOf[i] := random(100);

msRecInfo := TMemoryStream.Create;
try
msRecInfo.WriteBuffer(arrOf[0], Length(arrOf) * SizeOf(Integer));
IdTCPClient1.IOHandler.Write(msRecInfo, 0, True);
finally
msRecInfo.Free;
end;
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
msRecInfo: TMemoryStream;
arrOf: Array of Integer;
i: Integer;
begin
msRecInfo := TMemoryStream.Create;
try
AContext.Connection.IOHandler.ReadStream(msRecInfo, -1, False);
SetLength(arrOf, msRecInfo.Size div SizeOf(Integer));
if Lenth(arrOf) > 0 then
begin
msRecInfo.Position := 0;
msRecInfo.ReadBuffer(arrOf[0], Length(arrOf) * SizeOf(Integer));
end;
finally
msRecInfo.Free;
end;
...
end;

或者,摆脱 TMemoryStream 并自行发送各个 Integer 值:

procedure TForm1.btnTestClick(Sender: TObject);
var
arrOf: Array of Integer;
i: Integer;
begin
SetLength(arrOf, 11);
for i := Low(arrOf) to High(arrOf) do
arrOf[i] := random(100);

IdTCPClient1.IOHandler.Write(Length(arrOf));
for I := Low(arrOf) to High(arrOf) do
IdTCPClient1.IOHandler.Write(arrOf[i]);
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
arrOf: Array of Integer;
i: Integer;
begin
i := AContext.Connection.IOHandler.ReadLongInt;
SetLength(arrOf, i);
for i := Low(arrOf) to High(arrOf) do
arrOf[i] := AContext.Connection.IOHandler.ReadLongInt;
...
end;

现在,话虽如此,直接在 OnExecute 事件处理程序中访问 TMemo 不是线程安全的。 TIdTCPServer 是一个多线程组件。 OnExecute 事件在工作线程的上下文中触发,而不是主线程。 UI 组件,如 TMemo,不能从主线程之外安全地访问。可以使用 Indy 的 TIdNotifyTIdSync 类与主线程同步,eg:

type
TMemoSync = class(TIdSync)
protected
FLine: String;
procedure DoSynchronize; override;
end;

procedure TMemoSync.DoSynchronize;
begin
Form1.Memo1.Lines.Add(FLine);
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
...
begin
...
with TMemoSync.Create do try
FLine := IntToStr(arrOf[1]);
Synchronize;
finally
Free;
end;
...
end;

如果不与主线程同步,就会发生不好的事情。

关于delphi - IndyTCP delphi对象数组交换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13502814/

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