indy的idTcpServer WriteBuffer 有内存储器泄露
indy的idTcpServer WriteBuffer 有内存泄露?
用的是indy的demo程序改的,idtcpserver在接到客户端消息后,再返回客户端这个消息,服务器的内存一直在增加。如果不返回消息那么内存不增加。 为什么?????
结构体:
TCCPacked = record
lenLow: Byte;
lenHigh: Byte;
OPR: Byte;
ERR: Byte;
CMD: Byte;
end;
服务端代码:
procedure TServerFrmMain.ServerExecute(AThread: TIdPeerThread);
var
TCCPACK :TCCpacked;
size: Integer;
dataarray: array of byte;
begin
if not AThread.Terminated and AThread.Connection.Connected then
begin
AThread.Connection.ReadBuffer (TCCPACK, SizeOf (TCCPacked));
size := makeword(tccpack.lenlow,tccpack.lenhigh);
setlength(dataarray,size-3); //获取长度
AThread.Connection.ReadBuffer (dataarray[0], size-3);
AThread.Connection.WriteBuffer (TCCPACK, SizeOf (TCCPacked), true); //注释掉这句话就不会内存泄露
end;
end;
客户端代码:
发送部分:
procedure TClientFrmMain.ButtonSendClick(Sender: TObject);
var
CommBlock : TCCpacked;
s : string;
sl : TstringList;
dataarray : array of byte;
i ,size: integer;
begin
CommBlock.OPR := $01;
CommBlock.ERR := $00;
CommBlock.CMD := strtoint(cbb_cmd.Text);
s := EditMessage.Text ;
sl := TstringList.Create;
Geteveryword(s,sl,' ');
setlength(dataarray,sl.Count);
for i := 0 to sl.Count -1 do begin
dataarray[i] := strtoint( sl.Strings[i]);
end;
size := sl.Count + 3;
sl.Free;
CommBlock.lenLow := Lo(size); // assign the data
CommBlock.lenHigh := Hi(size);
//先发送数据头
Client.WriteBuffer (CommBlock, SizeOf (CommBlock), true);
//再发送Data部分
Client.WriteBuffer (dataarray[0] , length (dataarray), true);
// Client.WriteBuffer (CommBlock, SizeOf (CommBlock), true);
end;
接收部分:
procedure TClientHandleThread.HandleInput;
begin
ClientFrmMain.mmo1.Lines.Add('Server Return: ' + inttostr(cb.ERR));
end;
procedure TClientHandleThread.Execute;
begin
while not Terminated do
begin
if not ClientFrmMain.Client.Connected then
Terminate
else
try
ClientFrmMain.Client.ReadBuffer(CB, SizeOf (CB));
Synchronize(HandleInput);
except
end;
end;
end;
解决重赏!!
------解决方案--------------------
你把AThread.Connection.WriteBuffer (TCCPACK, SizeOf (TCCPacked), true); 中的TCCPACK转换成array of byte的变量.
------解决方案--------------------
可以声明一个 TCCpacked的指针 ^ TCCpacked,new一个,然后传递,用完 dispose掉
------解决方案--------------------
楼上也是种解决方法。
你的问题主要在于没搞懂record跟array of byte的区别。
虽然你的TCCPacked = record也是由byte组成的,但在实际应用上它是分节的,就像台阶那样堆叠的。而array of byte是一条直线平铺的。因此,你用TCCPACK直发,只能发送第一节台阶,剩余的哪里去?只能堆在你的记忆体中。
------解决方案--------------------
用的是indy的demo程序改的,idtcpserver在接到客户端消息后,再返回客户端这个消息,服务器的内存一直在增加。如果不返回消息那么内存不增加。 为什么?????
结构体:
TCCPacked = record
lenLow: Byte;
lenHigh: Byte;
OPR: Byte;
ERR: Byte;
CMD: Byte;
end;
服务端代码:
procedure TServerFrmMain.ServerExecute(AThread: TIdPeerThread);
var
TCCPACK :TCCpacked;
size: Integer;
dataarray: array of byte;
begin
if not AThread.Terminated and AThread.Connection.Connected then
begin
AThread.Connection.ReadBuffer (TCCPACK, SizeOf (TCCPacked));
size := makeword(tccpack.lenlow,tccpack.lenhigh);
setlength(dataarray,size-3); //获取长度
AThread.Connection.ReadBuffer (dataarray[0], size-3);
AThread.Connection.WriteBuffer (TCCPACK, SizeOf (TCCPacked), true); //注释掉这句话就不会内存泄露
end;
end;
客户端代码:
发送部分:
procedure TClientFrmMain.ButtonSendClick(Sender: TObject);
var
CommBlock : TCCpacked;
s : string;
sl : TstringList;
dataarray : array of byte;
i ,size: integer;
begin
CommBlock.OPR := $01;
CommBlock.ERR := $00;
CommBlock.CMD := strtoint(cbb_cmd.Text);
s := EditMessage.Text ;
sl := TstringList.Create;
Geteveryword(s,sl,' ');
setlength(dataarray,sl.Count);
for i := 0 to sl.Count -1 do begin
dataarray[i] := strtoint( sl.Strings[i]);
end;
size := sl.Count + 3;
sl.Free;
CommBlock.lenLow := Lo(size); // assign the data
CommBlock.lenHigh := Hi(size);
//先发送数据头
Client.WriteBuffer (CommBlock, SizeOf (CommBlock), true);
//再发送Data部分
Client.WriteBuffer (dataarray[0] , length (dataarray), true);
// Client.WriteBuffer (CommBlock, SizeOf (CommBlock), true);
end;
接收部分:
procedure TClientHandleThread.HandleInput;
begin
ClientFrmMain.mmo1.Lines.Add('Server Return: ' + inttostr(cb.ERR));
end;
procedure TClientHandleThread.Execute;
begin
while not Terminated do
begin
if not ClientFrmMain.Client.Connected then
Terminate
else
try
ClientFrmMain.Client.ReadBuffer(CB, SizeOf (CB));
Synchronize(HandleInput);
except
end;
end;
end;
解决重赏!!
------解决方案--------------------
你把AThread.Connection.WriteBuffer (TCCPACK, SizeOf (TCCPacked), true); 中的TCCPACK转换成array of byte的变量.
------解决方案--------------------
可以声明一个 TCCpacked的指针 ^ TCCpacked,new一个,然后传递,用完 dispose掉
------解决方案--------------------
楼上也是种解决方法。
你的问题主要在于没搞懂record跟array of byte的区别。
虽然你的TCCPacked = record也是由byte组成的,但在实际应用上它是分节的,就像台阶那样堆叠的。而array of byte是一条直线平铺的。因此,你用TCCPACK直发,只能发送第一节台阶,剩余的哪里去?只能堆在你的记忆体中。
------解决方案--------------------
- Delphi(Pascal) code
record记录集,要改成PCCPacked = ^TCCPacked var ppack:PCCPacked ; try GetMem(ppack,Sizeof(TCCPacked )); ReadBuffer(ppack,Sizeof(TCCPacked)); finally FreeMem(ppack); end;