我做一个网络设备(交换机,路由器等)数据采集系统,我使用的ipworks的snmpmgr控件,我做的是多线程采集多个设备,一个线程采集一个设备,当我运行程序的时候,只启动一个线程,程序正确,当启动两个的时候就出错了,错误提示:
109 The component must be Active for this operation.
下面是线程代码:
unit SnmpDataSampUnit;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ipwcore, ipwsnmpmgr, ExtCtrls, DB, ADODB, comObj, ActiveX;type
SnmpDataSamp = class(TThread)
private
{ Private declarations }
Fsnmp:tipwsnmpmgr;
Ftimer:ttimer;
Fsamptime:integer;
Fipaddress:string;
Fsnmpver:integer;//v1=1;v2c=2;v3=3;
FAdoConn:TADOConnection;
FADOQuery:TADOQuery;
procedure ontimer(sender:tobject);
procedure sampledata;
protected
procedure Execute; override;
destructor Destroy; override;
public
constructor create(ipaddress:string;fsamptime:integer;snmpver:integer;user:string;pw:string);
end;implementation{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure SnmpDataSamp.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }{ SnmpDataSamp }
constructor SnmpDataSamp.create(ipaddress:string;fsamptime:integer;snmpver:integer;user:string;pw:string);
begin
//-----------------------------------------------------------------------------//
FreeOnTerminate:=false;
Fsnmp:=tipwsnmpmgr.Create(nil);
Ftimer:=ttimer.Create(nil);
Ftimer.Interval:=fsamptime*1000;
ftimer.Enabled:=false;
fsnmp.RemoteHost:=ipaddress;
fsnmp.Community:='public';
if snmpver=1 then
begin
fsnmp.SNMPVersion:=TipwsnmpmgrSNMPVersions(1);
fsnmp.User:='';
fsnmp.Password:='';
end
else if snmpver=2 then
begin
fsnmp.SNMPVersion:=TipwsnmpmgrSNMPVersions(2);
fsnmp.User:='';
fsnmp.Password:='';
end
else begin
fsnmp.SNMPVersion:=TipwsnmpmgrSNMPVersions(3);
fsnmp.User:=user;
fsnmp.Password:=pw;
end;
//-----------------------------------------------------------------------------//
CoInitialize(nil);
FAdoConn:=TAdoconnection.Create(nil);
FAdoConn.LoginPrompt:=false;
FAdoConn.ConnectionString:='Provider=SQLOLEDB.1;Password=nmss;Persist Security Info=True;User ID=nmss;Initial Catalog=NMSD;Data Source=WTY';
FAdoQuery:=TAdoQuery.Create(nil);
FAdoQuery.Connection:=FAdoConn;
try
FAdoConn.Connected:=true;
except
showmessage('不能连接数据库!');
exit;
end;//-----------------------------------------------------------------------------//
inherited create(false);
end;
//-----------------------------------------------------------------------------//
destructor SnmpDataSamp.Destroy;
begin
inherited destroy;
Fsnmp.Active:=false;
fsnmp.Free;
ftimer.Enabled:=false;
ftimer.Free;
CoUninitialize;
FAdoquery.Free;
FAdoconn.Connected:=false;
FAdoconn.Free;
end;
//-----------------------------------------------------------------------------//
procedure SnmpDataSamp.sampledata;
var
i:integer;
j,portcount,k:integer;
valuestr:tstrings;
timestr:string;
sqlstr:string;
begin
fsnmp.Active:=false;
try
timestr:=datetimetostr(now);
valuestr:=tstringlist.Create;
valuestr.Clear;
fsnmp.ObjCount:=1;
fsnmp.ObjId[1]:='1.3.6.1.2.1.2.1.0'; fsnmp.Active:=true;// fsnmp.SendGetRequest;
portcount:=strtoint(fsnmp.ObjValue[1]); fsnmp.Active:=false;// i:=strtoint(fsnmp.ObjValue[1])*22;
fsnmp.ObjId[1]:='1.3.6.1.2.1.2.2'; while i>0 do
begin
fsnmp.Active:=true;///
fsnmp.SendGetNextRequest;
valuestr.Add(fsnmp.ObjValue[1]);
dec(i);
fsnmp.Active:=false;///
end;
for j:=0 to portcount-1 do
begin
////////////////////////////////////
sqlstr:='insert into datatable (ipaddress,dtstr,port,mtu,speed,portadstate,portoperstate,lastchange,inoctets,inucastpkts,innucastpkts,indiscards,inerrors,inunknownprotos,outoctets,outucastpkts,outnucastpkts,outdiscards,outerrors,outqlen)';
sqlstr:=sqlstr+' values('''+Fsnmp.RemoteHost+''',';
sqlstr:=sqlstr+''''+timestr+''',';
for k:=0 to 21 do
begin
if ((k=1) or (k=2) or (k=5) or (k=21)) then
continue
else begin
/////////////////////////////
if K<>20 then
sqlstr:=sqlstr+''''+valuestr.Strings[k*portcount+j]+''','
else sqlstr:=sqlstr+''''+valuestr.Strings[k*portcount+j]+''')';
end;
end;
///////////////////////////////
with Fadoquery do
begin
close;
sql.Clear;
sql.Text:=sqlstr;
Execsql;
end;
end;
finally
valuestr.Free;
end;end;//-----------------------------------------------------------------------------//
procedure SnmpDataSamp.ontimer(Sender:Tobject);
begin
Synchronize(sampledata);
end;//-----------------------------------------------------------------------------//
procedure SnmpDataSamp.Execute;
begin
{ Place thread code here }
ftimer.OnTimer:=ontimer;
ftimer.Enabled:=true;
end;end.
测试代码:
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, SnmpDataSampUnit, StdCtrls, ipwcore, ipwsnmpmgr;type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
ipwSNMPMgr1: TipwSNMPMgr;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
snmp1,snmp2:snmpdatasamp;
implementation
{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
///
snmp1:=SnmpDataSamp.create('202.202.41.173',30,1,'','');
end;procedure TForm1.Button2Click(Sender: TObject);
begin
////
snmp2:=SnmpDataSamp.create('202.202.41.175',30,1,'','');
end;end.
109 The component must be Active for this operation.
下面是线程代码:
unit SnmpDataSampUnit;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ipwcore, ipwsnmpmgr, ExtCtrls, DB, ADODB, comObj, ActiveX;type
SnmpDataSamp = class(TThread)
private
{ Private declarations }
Fsnmp:tipwsnmpmgr;
Ftimer:ttimer;
Fsamptime:integer;
Fipaddress:string;
Fsnmpver:integer;//v1=1;v2c=2;v3=3;
FAdoConn:TADOConnection;
FADOQuery:TADOQuery;
procedure ontimer(sender:tobject);
procedure sampledata;
protected
procedure Execute; override;
destructor Destroy; override;
public
constructor create(ipaddress:string;fsamptime:integer;snmpver:integer;user:string;pw:string);
end;implementation{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure SnmpDataSamp.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }{ SnmpDataSamp }
constructor SnmpDataSamp.create(ipaddress:string;fsamptime:integer;snmpver:integer;user:string;pw:string);
begin
//-----------------------------------------------------------------------------//
FreeOnTerminate:=false;
Fsnmp:=tipwsnmpmgr.Create(nil);
Ftimer:=ttimer.Create(nil);
Ftimer.Interval:=fsamptime*1000;
ftimer.Enabled:=false;
fsnmp.RemoteHost:=ipaddress;
fsnmp.Community:='public';
if snmpver=1 then
begin
fsnmp.SNMPVersion:=TipwsnmpmgrSNMPVersions(1);
fsnmp.User:='';
fsnmp.Password:='';
end
else if snmpver=2 then
begin
fsnmp.SNMPVersion:=TipwsnmpmgrSNMPVersions(2);
fsnmp.User:='';
fsnmp.Password:='';
end
else begin
fsnmp.SNMPVersion:=TipwsnmpmgrSNMPVersions(3);
fsnmp.User:=user;
fsnmp.Password:=pw;
end;
//-----------------------------------------------------------------------------//
CoInitialize(nil);
FAdoConn:=TAdoconnection.Create(nil);
FAdoConn.LoginPrompt:=false;
FAdoConn.ConnectionString:='Provider=SQLOLEDB.1;Password=nmss;Persist Security Info=True;User ID=nmss;Initial Catalog=NMSD;Data Source=WTY';
FAdoQuery:=TAdoQuery.Create(nil);
FAdoQuery.Connection:=FAdoConn;
try
FAdoConn.Connected:=true;
except
showmessage('不能连接数据库!');
exit;
end;//-----------------------------------------------------------------------------//
inherited create(false);
end;
//-----------------------------------------------------------------------------//
destructor SnmpDataSamp.Destroy;
begin
inherited destroy;
Fsnmp.Active:=false;
fsnmp.Free;
ftimer.Enabled:=false;
ftimer.Free;
CoUninitialize;
FAdoquery.Free;
FAdoconn.Connected:=false;
FAdoconn.Free;
end;
//-----------------------------------------------------------------------------//
procedure SnmpDataSamp.sampledata;
var
i:integer;
j,portcount,k:integer;
valuestr:tstrings;
timestr:string;
sqlstr:string;
begin
fsnmp.Active:=false;
try
timestr:=datetimetostr(now);
valuestr:=tstringlist.Create;
valuestr.Clear;
fsnmp.ObjCount:=1;
fsnmp.ObjId[1]:='1.3.6.1.2.1.2.1.0'; fsnmp.Active:=true;// fsnmp.SendGetRequest;
portcount:=strtoint(fsnmp.ObjValue[1]); fsnmp.Active:=false;// i:=strtoint(fsnmp.ObjValue[1])*22;
fsnmp.ObjId[1]:='1.3.6.1.2.1.2.2'; while i>0 do
begin
fsnmp.Active:=true;///
fsnmp.SendGetNextRequest;
valuestr.Add(fsnmp.ObjValue[1]);
dec(i);
fsnmp.Active:=false;///
end;
for j:=0 to portcount-1 do
begin
////////////////////////////////////
sqlstr:='insert into datatable (ipaddress,dtstr,port,mtu,speed,portadstate,portoperstate,lastchange,inoctets,inucastpkts,innucastpkts,indiscards,inerrors,inunknownprotos,outoctets,outucastpkts,outnucastpkts,outdiscards,outerrors,outqlen)';
sqlstr:=sqlstr+' values('''+Fsnmp.RemoteHost+''',';
sqlstr:=sqlstr+''''+timestr+''',';
for k:=0 to 21 do
begin
if ((k=1) or (k=2) or (k=5) or (k=21)) then
continue
else begin
/////////////////////////////
if K<>20 then
sqlstr:=sqlstr+''''+valuestr.Strings[k*portcount+j]+''','
else sqlstr:=sqlstr+''''+valuestr.Strings[k*portcount+j]+''')';
end;
end;
///////////////////////////////
with Fadoquery do
begin
close;
sql.Clear;
sql.Text:=sqlstr;
Execsql;
end;
end;
finally
valuestr.Free;
end;end;//-----------------------------------------------------------------------------//
procedure SnmpDataSamp.ontimer(Sender:Tobject);
begin
Synchronize(sampledata);
end;//-----------------------------------------------------------------------------//
procedure SnmpDataSamp.Execute;
begin
{ Place thread code here }
ftimer.OnTimer:=ontimer;
ftimer.Enabled:=true;
end;end.
测试代码:
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, SnmpDataSampUnit, StdCtrls, ipwcore, ipwsnmpmgr;type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
ipwSNMPMgr1: TipwSNMPMgr;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
snmp1,snmp2:snmpdatasamp;
implementation
{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
///
snmp1:=SnmpDataSamp.create('202.202.41.173',30,1,'','');
end;procedure TForm1.Button2Click(Sender: TObject);
begin
////
snmp2:=SnmpDataSamp.create('202.202.41.175',30,1,'','');
end;end.
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货