各位大大,本人写的程序是这样的,由于源码太多太多,只能贴有问题的部分,请各位大大,帮忙解决:
操作过程:
选择lisview1的一个选项,listview1的显示方式为vsReport,点击按钮,向远程客户端发送连接命令,由于每一个项代表一个远程的客户端,所以点击该按钮
就代表操作该主机,此处为控制端代码:procedure TForm1.Button5Click(Sender: TObject);
begin if form1.listview1.Selected <> nil then
begin
if listview1.Selected.SubItems.Objects[2] <> nil then
begin
showmessage('进程监控已经在运行了!');
exit;
end;
spyitem:=form1.listview1.Selected;
form1.Enabled:=false;
sendcmd('014', edit5.text, True); // 用一个在线套接字,发送消息
beginspy:=false;
end;
end;
然后
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
RecCMD: string; pitem:tlistitem;
rs, ss: TMemoryStream;
pCmd: array[0..SizeOf(TSpyCmd) - 1] of Byte;
pBuf: array[0..8191] of Byte;
Read, Size: Integer;
//spyobjects:Tobjects;
begin RecCMD := AThread.Connection.readln(EOL);
//RecCMD := DecodeBase64(RecCMD);
//showmessage(reccmd);
if Length(RecCMD)>5 then Exit; ... ...
if AThread.Connection.Tag = 4 then //进程管理
begin
UserProc(AThread, RecCMD);
Exit;
end;
end;这是 userproc函数的相关代码:
procedure UserProc(AThread: TIdPeerThread; RecCMD: string);
function getfilesize(str: string): string;
{=======================进程管理=========================}
if reccmd = '004' then //进程管理
begin
athread.Connection.Tag:=4; //此处为远程主机新建的一个套接字,标示为4
//process_form.show;
athread.data:=spyitem;
tonlineinf(spyitem.data^).process_atrhread:=athread;
athread.Synchronize(form1.show_process); //sleep(100);
//while athread.Connection.Connected do
//begin
end;
if reccmd = '012' then //进程管理
begin
if form1.readseverstream(athread,tempstr) then
begin
Temp_process:=tstringlist.Create;
temp_process.Text:=tempstr;
pitem:=tlistitem(athread.data);
for i:=0 to temp_process.Count-1 do
begin
with tprocess_form(pitem.SubItems.Objects[2]).ListView1.Items.Add do
begin
Caption:= form1.centerstr(temp_process[i],'<pr_name>','</pr_name>');
SubItems.Add(form1.centerstr(temp_process[i],'<pr_id>','</pr_id>'));
SubItems.Add(form1.centerstr(temp_process[i],'<pr_path>','</pr_path>'));
end;
end;
//showmessage(tempstr); end;
//end;
end;
end;这是显示窗体的过程
procedure tform1.show_process;
var
process_form:Tprocess_form;
begin
process_form:=Tprocess_form.Create(self);
//tonlineinf(spyitem.data^).process_atrhread.Data:=spyitem;
spyitem.SubItems.Objects[2]:=process_form;
process_form.pitem:=spyitem; tonlineinf(spyitem.data^).process_atrhread.Connection.Write('004'+EOL);
form1.Enabled:=true;
process_form.Show;
end;在下搞不懂的是,点listview1第一个项,能正常工作,可是
点多了listview1项,偶尔会发现listview1某项的数据会被修改
请问如何解决:
listview1的数据结构
主机IP 标识ID 计算机名称 操作系统
127.0.01 2037 winpc winxp sp2
...
...
...执行上面操作的时候,会变成这样
主机IP 标识ID 计算机名称 操作系统
127.0.01 (乱码或者没有数据) winpc winxp sp2
...
...
...
里面任决一列的数据都会被改写,改写的数据是随机的
操作过程:
选择lisview1的一个选项,listview1的显示方式为vsReport,点击按钮,向远程客户端发送连接命令,由于每一个项代表一个远程的客户端,所以点击该按钮
就代表操作该主机,此处为控制端代码:procedure TForm1.Button5Click(Sender: TObject);
begin if form1.listview1.Selected <> nil then
begin
if listview1.Selected.SubItems.Objects[2] <> nil then
begin
showmessage('进程监控已经在运行了!');
exit;
end;
spyitem:=form1.listview1.Selected;
form1.Enabled:=false;
sendcmd('014', edit5.text, True); // 用一个在线套接字,发送消息
beginspy:=false;
end;
end;
然后
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
RecCMD: string; pitem:tlistitem;
rs, ss: TMemoryStream;
pCmd: array[0..SizeOf(TSpyCmd) - 1] of Byte;
pBuf: array[0..8191] of Byte;
Read, Size: Integer;
//spyobjects:Tobjects;
begin RecCMD := AThread.Connection.readln(EOL);
//RecCMD := DecodeBase64(RecCMD);
//showmessage(reccmd);
if Length(RecCMD)>5 then Exit; ... ...
if AThread.Connection.Tag = 4 then //进程管理
begin
UserProc(AThread, RecCMD);
Exit;
end;
end;这是 userproc函数的相关代码:
procedure UserProc(AThread: TIdPeerThread; RecCMD: string);
function getfilesize(str: string): string;
{=======================进程管理=========================}
if reccmd = '004' then //进程管理
begin
athread.Connection.Tag:=4; //此处为远程主机新建的一个套接字,标示为4
//process_form.show;
athread.data:=spyitem;
tonlineinf(spyitem.data^).process_atrhread:=athread;
athread.Synchronize(form1.show_process); //sleep(100);
//while athread.Connection.Connected do
//begin
end;
if reccmd = '012' then //进程管理
begin
if form1.readseverstream(athread,tempstr) then
begin
Temp_process:=tstringlist.Create;
temp_process.Text:=tempstr;
pitem:=tlistitem(athread.data);
for i:=0 to temp_process.Count-1 do
begin
with tprocess_form(pitem.SubItems.Objects[2]).ListView1.Items.Add do
begin
Caption:= form1.centerstr(temp_process[i],'<pr_name>','</pr_name>');
SubItems.Add(form1.centerstr(temp_process[i],'<pr_id>','</pr_id>'));
SubItems.Add(form1.centerstr(temp_process[i],'<pr_path>','</pr_path>'));
end;
end;
//showmessage(tempstr); end;
//end;
end;
end;这是显示窗体的过程
procedure tform1.show_process;
var
process_form:Tprocess_form;
begin
process_form:=Tprocess_form.Create(self);
//tonlineinf(spyitem.data^).process_atrhread.Data:=spyitem;
spyitem.SubItems.Objects[2]:=process_form;
process_form.pitem:=spyitem; tonlineinf(spyitem.data^).process_atrhread.Connection.Write('004'+EOL);
form1.Enabled:=true;
process_form.Show;
end;在下搞不懂的是,点listview1第一个项,能正常工作,可是
点多了listview1项,偶尔会发现listview1某项的数据会被修改
请问如何解决:
listview1的数据结构
主机IP 标识ID 计算机名称 操作系统
127.0.01 2037 winpc winxp sp2
...
...
...执行上面操作的时候,会变成这样
主机IP 标识ID 计算机名称 操作系统
127.0.01 (乱码或者没有数据) winpc winxp sp2
...
...
...
里面任决一列的数据都会被改写,改写的数据是随机的
1.线程里Sendmessae,界面窗口来处理消息,刷新屏幕
2.线程里必须用Synchronize 的方法来刷新屏幕!
我的指针指向的是动态数组的元素`` 动态数组的内存空间是不连续的``
也就是说动态数组的元素地址会随时变化,我指的时候是一个地址,经过一轮数据操作,元素的头地址会发生变化,指针却仍指向原来的地址,所以强制访问指针的话,指针所指向的内存,有可能是listview1的空间,所以listview1会出现乱码``
贴上出错的代码```结构声明
type // 服务器的会话信息。
Tonlineinf = record
ServerName: string[30]; {服务器主机名称}
AThread : TIdPeerThread; {服务器线程}
Soc: integer; {服务器线程ID}
Online: Boolean; {是否在线}
ServerAdd: string[15]; {服务器IP地址}
AdderStr: string; {地理位置}
spythread:TIdPeerThread; {屏幕监控}
process_atrhread:tidpeerthread;{进程监控}
telnet_athread:tidpeerthread;{远程telnet}
keyboard_athread:tidpeerthread;{键盘记录}
data,data2:pointer;
end;
全局变量数组声明:
OnlineServer: array of Tonlineinf;出错的过程
procedure UserProc(AThread: TIdPeerThread; RecCMD: string);
if reccmd = '000' then
begin AThread.Connection.Tag := 0;
enterCriticalSection(upline);
j := -1;
for i := 1 to OnlineCount do {查找是否有空白项}
begin
if not OnlineServer[i-1].Online then
begin
j := i - 1; {有,分配它}
OnlineServer[j].Online := true; {置为在线}
break;
end;
end; if j = -1 then
begin {无,新增一个}
j := OnlineCount;
inc(OnlineCount);
Setlength(OnlineServer, OnlineCount);
OnlineServer[j].Online := True; {置为在用}
end; OnlineServer[j].AThread :=AThread;
onlineserver[j].spythread:=nil;
onlineserver[j].process_atrhread:=nil;
onlineserver[j].keyboard_athread:=nil;
onlineserver[j].telnet_athread:=nil;
OnlineServer[j].Soc := AThread.ThreadID ;
OnlineServer[j].ServerAdd := AThread.Connection.Socket.Binding.PeerIP;
OnlineServer[j].ServerName := AThread.Connection.Socket.Binding.PeerIP + '-' + inttoStr(AThread.ThreadID); if form1.readseverstream(athread,tempstr) then
begin
with form1.ListView1.Items.Add do
begin
Caption:= AThread.Connection.Socket.Binding.PeerIP;
SubItems.Add(inttostr(AThread.ThreadID));
SubItems.Add(form1.centerstr(tempstr,'<host>','</host>'));
SubItems.Add(form1.centerstr(tempstr,'<os>','</os>'));
SubItems.Add('');
SubItems.Add(form1.centerstr(tempstr,'<sp>','</sp>'));
SubItems.Add(inttostr(AThread.ThreadID));
data:=@OnlineServer[j]; //onlineserver为动态数组 //此处出错!!
OnlineServer[j].data:=subitems;
OnlineServer[j].data2:=data;
end;
//showmessage(tempstr);
end;... ...
end;