UDP的程序其实需求很简单。可是老是出内存泄露。我是在主界面一打开就实例化三个FRAME。这三个FRAME都是一个FRAME模板来的。在FRAME里有一开始测试按钮,这里面就会实例一个UDP对象,然后实现一个UDPSEND,UDPREV两个对象。在实现后两个对象的时候。传了当前这个FRAME的实例名过去。方便后面发送交互协议同步到界面MEMO上显示。我是一实例线程就让他跑。主要是想实现UDP的发和收分离。接一个线程归接。收另一个线程归收。共用一个UDP。用的是多线程。那线程停止的时候。我就在线程里把UDP给释放。不知道这样会不会有问题?
首先是实例在开始测试按钮里单击事件里:UDP := TUDPClient.Create(SocketInfo);
SendThread := TUDPSendThread.Create(False,cxgridlist,SocketInfo.IndyName,SocketInfo.Tag,SocketInfo.MsgFlag,self.UDP,Self);
RevThread := TUDPRevThread.Create(False,cxgridlist,SocketInfo.IndyName,SocketInfo.SavePath,SocketInfo.Tag,SocketInfo.MsgFlag,SocketInfo.SaveFileSize,Self.UDP,Self);程序有点难看。但不影响理解。我是想先实现以后再优化。
然后发送的线程
TUDPSendThread = class(TThread)
private
Flist:TList;
FTag:Integer;
Fudp:TUDPClient;
FName:string;
FFrame:TFrame;
p:PMEMOINFO;
public
FFlag:Integer;
constructor Create(Suspended:Boolean;aSendList:Tlist;aName:string;aTag,aFlag:Integer;aUDP:TUDPClient;aframe:TFrame);
destructor Destroy; override;
procedure ManualSendData;
procedure SequenceSendData;
procedure RandomSendData;
procedure SendToMemo(aUDPstr:string);
procedure Execute;override;
end;
{ TUDPSendThread }constructor TUDPSendThread.Create(Suspended: Boolean; aSendList: Tlist;aName:string;
aTag,aFlag: Integer; aUDP: TUDPClient;aframe:TFrame);
begin
inherited Create(Suspended);
Flist := aSendList;
FTag := aTag;
FFlag := aFlag;
FUdp := aUDP;
FName := aName;
FFrame := aframe;
FreeOnTerminate:=True;
end;destructor TUDPSendThread.Destroy;
begin
// if Flist <> nil then
// FreeAndNil(Flist);
IF Fudp<>nil then FreeAndNil(Fudp);
inherited;
end;procedure TUDPSendThread.Execute;
var
i:Integer;
begin
inherited;
try
if Flist.Count > 0 then
begin
if FTag = sequenceSendFlag then //顺序循环
begin
//i:=0;
while not Terminated do
begin
if FUDP = nil then Self.Terminate;
ManualSendData;
//if i <Flist.Count-1 then Inc(i) else i:= 0;
end;
end
else if FTag = randomSendFlag then //随机循环
begin
while not Terminated do
begin
if FUDP = nil then Self.Terminate;
RandomSendData;
end;
end
else
begin
if FUDP = nil then Self.Terminate;
ManualSendData; //手动
end;
end;
finally
if Flist<>nil then
begin
for i:=0 to Flist.Count-1 do
begin
if Assigned(Flist[i]) then
begin
Dispose(PSendRecInfo(FList[i]));
end;
end;
end;
Flist.Free;
if FUDP <> nil then
FreeAndNil(FUDP);
end;
end;procedure TUDPSendThread.ManualSendData;
var
tempstr:string;
PSend:PSendRecInfo;
i,j:Integer;
begin
for i:=0 to Flist.Count-1 do
begin
PSend := Flist.Items[i];
for j:= 0 to Psend.RunTimes-1 do
begin
FUDP.setReceiveTimeOut(PSend.SpaceTime); //设置UDP接收时间
if FUDP.sendData(Psend.data) then
begin
if FFlag = 0 then
SendToMemo(GetNowTimeString+' 发送成功: '+ Psend.data); //发消息同步到主窗体显示
end
else
begin
if FFlag = 0 then
SendToMemo(GetNowTimeString+' 发送失败: '+Psend.data); //发消息同步到主窗体显示
end;
Sleep(PSend.SpaceTime);
end;
end;
end;
procedure TUDPSendThread.RandomSendData;
var
tempstr:string;
PSend:PSendRecInfo;
j:Integer;
begin
randomize;
PSend := Flist.Items[Random(Flist.Count-1)];
for j:= 0 to Psend.RunTimes-1 do
begin
FUDP.setReceiveTimeOut(PSend.SpaceTime); //设置UDP接收时间
if FUDP.sendData(Psend.data) then
begin
if FFlag = 0 then
SendToMemo(GetNowTimeString+' 发送成功: '+ Psend.data); //发消息同步到主窗体显示
end
else
begin
if FFlag = 0 then
SendToMemo(GetNowTimeString+' 发送失败: '+Psend.data); //发消息同步到主窗体显示
end;
Sleep(PSend.SpaceTime);
end;
end;procedure TUDPSendThread.SendToMemo(aUDPstr: string);
var
MyWindow:THandle;
begin
MyWindow := FFrame.Handle;
if MyWindow >0 then
begin
New(p);
P^.Flag := FFrame;
P^.Data := aUDPstr;
PostMessage(MyWindow,WM_MEMOINFO,0,LParam(p));
end;
end;procedure TUDPSendThread.SequenceSendData;
var
tempstr:string;
PSend:PSendRecInfo;
i,j:Integer;
begin
for i:=0 to Flist.Count-1 do
begin
PSend := Flist.Items[i];
for j:= 0 to Psend.RunTimes-1 do
begin
FUDP.setReceiveTimeOut(PSend.SpaceTime); //设置UDP接收时间
if FUDP.sendData(Psend.data) then
begin
if FFlag = 0 then
SendToMemo(GetNowTimeString+' 发送成功: '+ Psend.data); //发消息同步到主窗体显示
end
else
begin
if FFlag = 0 then
SendToMemo(GetNowTimeString+' 发送失败: '+Psend.data); //发消息同步到主窗体显示
end;
Sleep(PSend.SpaceTime);
end;
end;
end; TUDPRevThread = class(TThread)
private
Flist:TList;
FTag:Integer; //手动 、自动顺序、自动随机
FlogDir:string;
FUDP:TUDPClient;
FName:string;
FSaveFileSize:Integer;
FLog:TLog;
FFrame:TFrame;
R:PMEMOINFO;
public
FFlag:Integer; //是否要显示到MEMO 0否 1是
constructor Create(Suspended:Boolean;aRevList:Tlist;aName,aLogDir:string;aTag,aFlag,aSaveFileSize:Integer;aUDP:TUDPClient;aframe:TFrame);
destructor Destroy; override;
procedure SendToMemo(aUDPstr:string);
procedure Execute;override;
end;
{ TUDPRevThread }constructor TUDPRevThread.Create(Suspended:Boolean;aRevList:Tlist;aName,aLogDir:string;aTag,aFlag,aSaveFileSize:Integer;aUDP:TUDPClient;aframe:TFrame);
begin
inherited Create(Suspended);
Flist := aRevList;
FlogDir := aLogDir;
FTag := aTag;
FFlag := aFlag;
FUdp := aUDP;
FName := aName;
FSaveFileSize := aSaveFileSize;
FFrame := aFrame;
FLog := TLog.Create(FName,FlogDir,aSaveFileSize); FreeOnTerminate:=True;
end;destructor TUDPRevThread.Destroy;
var
i:Integer;
begin
if Flist <> nil then
begin
for i:=0 to Flist.Count-1 do
begin
if Assigned(Flist[i]) then
begin
Dispose(PSendRecInfo(FList[i]));
end;
end;
end;
Flist.Free;
if FUDP<> nil then FreeAndNil(FUDP);
if FLog <> nil then FreeAndNil(Flog);
inherited;
end;procedure TUDPRevThread.Execute;
var
RevList:TStringList;
RevStr:string;
i:Integer;
begin
inherited;
RevList := TStringList.Create;
try
if Flist.Count > 0 then
begin
if FTag = manualFlag then //手动
begin
if FUDP = nil then Self.Terminate;
while not Terminated do
begin
if FUDP.RevData(RevStr) then
RevStr := GetNowTimeString+' 接收成功: '+ RevStr; if RevStr <>'' then
RevList.Add(RevStr); if FFlag = 0 then
SendToMemo(RevStr); //发消息同步到主窗体显示
FLog.writetofile(RevList); //写入日志
RevList.Clear;
end;
end
else
begin
if FUDP = nil then Self.Terminate;
while not Terminated do
begin
if FUDP.revData(RevStr) then
RevStr := GetNowTimeString+' 接收成功: '+ RevStr;
if FFlag = 0 then
SendToMemo(RevStr); //发消息同步到主窗体显示 if RevStr <>'' then
RevList.Add(RevStr); if RevList.Count >= writeCount then
begin
FLog.writetofile(RevList);
RevList.Clear;
end;
end;
end;
end;
finally
if RevList.Count >0 then
begin
FLog.writetofile(RevList);
RevList.Clear;
end;
RevList.Free;
FreeAndNil(Flog); if Flist<>nil then
begin
for i:=0 to Flist.Count-1 do
begin
if Assigned(Flist[i]) then
begin
Dispose(PSendRecInfo(FList[i]));
end;
end;
end;
Flist.Free;
//if Flist<> nil then FreeAndNil(Flist);
if self.FUDP <> nil then
FreeAndNil(self.FUDP);
end;
end;
procedure TUDPRevThread.SendToMemo(aUDPstr: string);
var
MyWindow:THandle;
begin
MyWindow := FFrame.Handle;
if MyWindow >0 then
begin
New(R);
R^.Flag := FFrame;
R^.Data := aUDPstr;
PostMessage(MyWindow,WM_MEMOINFO,0,LParam(R));
end;
end;在线程执行后,严重内存泄露。请懂的帮忙。分数不够可以再加。我的QQ282567546,如果可以远程调下也行。
首先是实例在开始测试按钮里单击事件里:UDP := TUDPClient.Create(SocketInfo);
SendThread := TUDPSendThread.Create(False,cxgridlist,SocketInfo.IndyName,SocketInfo.Tag,SocketInfo.MsgFlag,self.UDP,Self);
RevThread := TUDPRevThread.Create(False,cxgridlist,SocketInfo.IndyName,SocketInfo.SavePath,SocketInfo.Tag,SocketInfo.MsgFlag,SocketInfo.SaveFileSize,Self.UDP,Self);程序有点难看。但不影响理解。我是想先实现以后再优化。
然后发送的线程
TUDPSendThread = class(TThread)
private
Flist:TList;
FTag:Integer;
Fudp:TUDPClient;
FName:string;
FFrame:TFrame;
p:PMEMOINFO;
public
FFlag:Integer;
constructor Create(Suspended:Boolean;aSendList:Tlist;aName:string;aTag,aFlag:Integer;aUDP:TUDPClient;aframe:TFrame);
destructor Destroy; override;
procedure ManualSendData;
procedure SequenceSendData;
procedure RandomSendData;
procedure SendToMemo(aUDPstr:string);
procedure Execute;override;
end;
{ TUDPSendThread }constructor TUDPSendThread.Create(Suspended: Boolean; aSendList: Tlist;aName:string;
aTag,aFlag: Integer; aUDP: TUDPClient;aframe:TFrame);
begin
inherited Create(Suspended);
Flist := aSendList;
FTag := aTag;
FFlag := aFlag;
FUdp := aUDP;
FName := aName;
FFrame := aframe;
FreeOnTerminate:=True;
end;destructor TUDPSendThread.Destroy;
begin
// if Flist <> nil then
// FreeAndNil(Flist);
IF Fudp<>nil then FreeAndNil(Fudp);
inherited;
end;procedure TUDPSendThread.Execute;
var
i:Integer;
begin
inherited;
try
if Flist.Count > 0 then
begin
if FTag = sequenceSendFlag then //顺序循环
begin
//i:=0;
while not Terminated do
begin
if FUDP = nil then Self.Terminate;
ManualSendData;
//if i <Flist.Count-1 then Inc(i) else i:= 0;
end;
end
else if FTag = randomSendFlag then //随机循环
begin
while not Terminated do
begin
if FUDP = nil then Self.Terminate;
RandomSendData;
end;
end
else
begin
if FUDP = nil then Self.Terminate;
ManualSendData; //手动
end;
end;
finally
if Flist<>nil then
begin
for i:=0 to Flist.Count-1 do
begin
if Assigned(Flist[i]) then
begin
Dispose(PSendRecInfo(FList[i]));
end;
end;
end;
Flist.Free;
if FUDP <> nil then
FreeAndNil(FUDP);
end;
end;procedure TUDPSendThread.ManualSendData;
var
tempstr:string;
PSend:PSendRecInfo;
i,j:Integer;
begin
for i:=0 to Flist.Count-1 do
begin
PSend := Flist.Items[i];
for j:= 0 to Psend.RunTimes-1 do
begin
FUDP.setReceiveTimeOut(PSend.SpaceTime); //设置UDP接收时间
if FUDP.sendData(Psend.data) then
begin
if FFlag = 0 then
SendToMemo(GetNowTimeString+' 发送成功: '+ Psend.data); //发消息同步到主窗体显示
end
else
begin
if FFlag = 0 then
SendToMemo(GetNowTimeString+' 发送失败: '+Psend.data); //发消息同步到主窗体显示
end;
Sleep(PSend.SpaceTime);
end;
end;
end;
procedure TUDPSendThread.RandomSendData;
var
tempstr:string;
PSend:PSendRecInfo;
j:Integer;
begin
randomize;
PSend := Flist.Items[Random(Flist.Count-1)];
for j:= 0 to Psend.RunTimes-1 do
begin
FUDP.setReceiveTimeOut(PSend.SpaceTime); //设置UDP接收时间
if FUDP.sendData(Psend.data) then
begin
if FFlag = 0 then
SendToMemo(GetNowTimeString+' 发送成功: '+ Psend.data); //发消息同步到主窗体显示
end
else
begin
if FFlag = 0 then
SendToMemo(GetNowTimeString+' 发送失败: '+Psend.data); //发消息同步到主窗体显示
end;
Sleep(PSend.SpaceTime);
end;
end;procedure TUDPSendThread.SendToMemo(aUDPstr: string);
var
MyWindow:THandle;
begin
MyWindow := FFrame.Handle;
if MyWindow >0 then
begin
New(p);
P^.Flag := FFrame;
P^.Data := aUDPstr;
PostMessage(MyWindow,WM_MEMOINFO,0,LParam(p));
end;
end;procedure TUDPSendThread.SequenceSendData;
var
tempstr:string;
PSend:PSendRecInfo;
i,j:Integer;
begin
for i:=0 to Flist.Count-1 do
begin
PSend := Flist.Items[i];
for j:= 0 to Psend.RunTimes-1 do
begin
FUDP.setReceiveTimeOut(PSend.SpaceTime); //设置UDP接收时间
if FUDP.sendData(Psend.data) then
begin
if FFlag = 0 then
SendToMemo(GetNowTimeString+' 发送成功: '+ Psend.data); //发消息同步到主窗体显示
end
else
begin
if FFlag = 0 then
SendToMemo(GetNowTimeString+' 发送失败: '+Psend.data); //发消息同步到主窗体显示
end;
Sleep(PSend.SpaceTime);
end;
end;
end; TUDPRevThread = class(TThread)
private
Flist:TList;
FTag:Integer; //手动 、自动顺序、自动随机
FlogDir:string;
FUDP:TUDPClient;
FName:string;
FSaveFileSize:Integer;
FLog:TLog;
FFrame:TFrame;
R:PMEMOINFO;
public
FFlag:Integer; //是否要显示到MEMO 0否 1是
constructor Create(Suspended:Boolean;aRevList:Tlist;aName,aLogDir:string;aTag,aFlag,aSaveFileSize:Integer;aUDP:TUDPClient;aframe:TFrame);
destructor Destroy; override;
procedure SendToMemo(aUDPstr:string);
procedure Execute;override;
end;
{ TUDPRevThread }constructor TUDPRevThread.Create(Suspended:Boolean;aRevList:Tlist;aName,aLogDir:string;aTag,aFlag,aSaveFileSize:Integer;aUDP:TUDPClient;aframe:TFrame);
begin
inherited Create(Suspended);
Flist := aRevList;
FlogDir := aLogDir;
FTag := aTag;
FFlag := aFlag;
FUdp := aUDP;
FName := aName;
FSaveFileSize := aSaveFileSize;
FFrame := aFrame;
FLog := TLog.Create(FName,FlogDir,aSaveFileSize); FreeOnTerminate:=True;
end;destructor TUDPRevThread.Destroy;
var
i:Integer;
begin
if Flist <> nil then
begin
for i:=0 to Flist.Count-1 do
begin
if Assigned(Flist[i]) then
begin
Dispose(PSendRecInfo(FList[i]));
end;
end;
end;
Flist.Free;
if FUDP<> nil then FreeAndNil(FUDP);
if FLog <> nil then FreeAndNil(Flog);
inherited;
end;procedure TUDPRevThread.Execute;
var
RevList:TStringList;
RevStr:string;
i:Integer;
begin
inherited;
RevList := TStringList.Create;
try
if Flist.Count > 0 then
begin
if FTag = manualFlag then //手动
begin
if FUDP = nil then Self.Terminate;
while not Terminated do
begin
if FUDP.RevData(RevStr) then
RevStr := GetNowTimeString+' 接收成功: '+ RevStr; if RevStr <>'' then
RevList.Add(RevStr); if FFlag = 0 then
SendToMemo(RevStr); //发消息同步到主窗体显示
FLog.writetofile(RevList); //写入日志
RevList.Clear;
end;
end
else
begin
if FUDP = nil then Self.Terminate;
while not Terminated do
begin
if FUDP.revData(RevStr) then
RevStr := GetNowTimeString+' 接收成功: '+ RevStr;
if FFlag = 0 then
SendToMemo(RevStr); //发消息同步到主窗体显示 if RevStr <>'' then
RevList.Add(RevStr); if RevList.Count >= writeCount then
begin
FLog.writetofile(RevList);
RevList.Clear;
end;
end;
end;
end;
finally
if RevList.Count >0 then
begin
FLog.writetofile(RevList);
RevList.Clear;
end;
RevList.Free;
FreeAndNil(Flog); if Flist<>nil then
begin
for i:=0 to Flist.Count-1 do
begin
if Assigned(Flist[i]) then
begin
Dispose(PSendRecInfo(FList[i]));
end;
end;
end;
Flist.Free;
//if Flist<> nil then FreeAndNil(Flist);
if self.FUDP <> nil then
FreeAndNil(self.FUDP);
end;
end;
procedure TUDPRevThread.SendToMemo(aUDPstr: string);
var
MyWindow:THandle;
begin
MyWindow := FFrame.Handle;
if MyWindow >0 then
begin
New(R);
R^.Flag := FFrame;
R^.Data := aUDPstr;
PostMessage(MyWindow,WM_MEMOINFO,0,LParam(R));
end;
end;在线程执行后,严重内存泄露。请懂的帮忙。分数不够可以再加。我的QQ282567546,如果可以远程调下也行。
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货