我们正在开发Delphi XE5程序,以监控本地网络中的MFP。重要的是,对于每个传入的SNMP陷阱通知,我们都能够确定发送它的MFP。似乎TIdSNMP.ReceiveTrap将自上次调用以来收到的每个通知放入TIdSNMP.Trap.Value数组属性的元素中;然后,TIdSNMP.Trap.Host包含发送最新陷阱通知的MFP的IP地址。有人可以证实这一点吗?有没有办法获得与TIdSNMP.Trap.Value的其他元素相对应的IP地址?
出于测试目的,我们使用以下代码来接收和显示SNMP陷阱消息:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages,
System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient, IdSNMP;
type
TForm1 = class(TForm)
Button2: TButton;
IdSNMP1: TIdSNMP;
Memo1: TMemo;
procedure Button2Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
procedure FormatTrap(ASnmpInfo : TSnmpInfo);
var
i : integer;
begin
Memo1.Lines.Add('{');
with ASnmpInfo do begin
Memo1.Lines.Add(Format('Host=%s, ', [Host]));
Memo1.Lines.Add(Format('Port=%d, ', [Port]));
Memo1.Lines.Add(Format('Enterprise=%s, ', [Enterprise]));
Memo1.Lines.Add(Format('GenTrap=%d, ', [GenTrap]));
Memo1.Lines.Add(Format('SpecTrap=%d, ', [SpecTrap]));
Memo1.Lines.Add(Format('Version=%d, ', [Version]));
Memo1.Lines.Add(Format('PDUType=%d, ', [PDUType]));
Memo1.Lines.Add(Format('TimeTicks=%d, ', [TimeTicks]));
Memo1.Lines.Add(Format('ID=%d, ', [ID]));
Memo1.Lines.Add(Format('ErrorStatus=%d, ', [ErrorStatus]));
Memo1.Lines.Add(Format('ErrorIndex=%d, ', [ErrorIndex]));
Memo1.Lines.Add(Format('Community=%s, ', [Community]));
Memo1.Lines.Add(Format('ValueCount=%d, ', [ValueCount]));
for i := 0 to ValueCount-1 do begin
Memo1.Lines.Add( Format('Value[%d]=%s, ', [i,Value[i]]));
Memo1.Lines.Add( Format('ValueOID[%d]=%s, ', [i,ValueOID[i]]));
Memo1.Lines.Add( Format('ValueType[%d]=%d, ', [i,ValueType[i]]));
end;
Memo1.Lines.Add('}');
end;
end;
begin
while not Application.Terminated do begin
if IdSNMP1.ReceiveTrap() then begin
FormatTrap(IdSNMP1.Trap);
end;
Sleep(100);
Application.ProcessMessages();
end;
end;
end.
两台MFP - 一台192.168.197.159下的柯尼卡美能达bizhub C364e和192.168.197.19下的柯尼卡美能达bizhub C364--已配置为向运行此程序的计算机发送SNMP陷阱通知。以下是一些示例结果:
{
Host=192.168.197.159,
Port=32884,
Enterprise=1.3.6.1.4.1.18334,
GenTrap=6,
SpecTrap=10,
Version=0,
PDUType=164,
TimeTicks=7792839,
ID=0,
ErrorStatus=0,
ErrorIndex=0,
Community=public,
ValueCount=5,
Value[0]=No Paper,
ValueOID[0]=1.3.6.1.4.1.18334.1.1.1.2.1.105.2.2,
ValueType[0]=4,
Value[1]=No Paper,
ValueOID[1]=1.3.6.1.4.1.18334.1.1.1.2.1.105.2.2,
ValueType[1]=4,
Value[2]=No Paper,
ValueOID[2]=1.3.6.1.4.1.18334.1.1.1.2.1.105.2.2,
ValueType[2]=4,
Value[3]=No Paper,
ValueOID[3]=1.3.6.1.4.1.18334.1.1.1.2.1.105.2.2,
ValueType[3]=4,
Value[4]=Job End,
ValueOID[4]=1.3.6.1.4.1.18334.1.1.1.2.1.105.2.2,
ValueType[4]=4,
}
{
Host=192.168.197.19,
Port=53365,
Enterprise=1.3.6.1.4.1.18334,
GenTrap=6,
SpecTrap=10,
Version=0,
PDUType=164,
TimeTicks=12469234,
ID=0,
ErrorStatus=0,
ErrorIndex=0,
Community=public,
ValueCount=6,
Value[0]=No Paper,
ValueOID[0]=1.3.6.1.4.1.18334.1.1.1.2.1.105.2.2,
ValueType[0]=4,
Value[1]=No Paper,
ValueOID[1]=1.3.6.1.4.1.18334.1.1.1.2.1.105.2.2,
ValueType[1]=4,
Value[2]=No Paper,
ValueOID[2]=1.3.6.1.4.1.18334.1.1.1.2.1.105.2.2,
ValueType[2]=4,
Value[3]=No Paper,
ValueOID[3]=1.3.6.1.4.1.18334.1.1.1.2.1.105.2.2,
ValueType[3]=4,
Value[4]=Job End,
ValueOID[4]=1.3.6.1.4.1.18334.1.1.1.2.1.105.2.2,
ValueType[4]=4,
Value[5]=Job End,
ValueOID[5]=1.3.6.1.4.1.18334.1.1.1.2.1.83.3.1,
ValueType[5]=4,
}
1.3.6.1.4.1.18334.1.1.1.2.1.105.2.2是C364e的SysObjectID和1.3.6.1.4.1.18334.1.1.1.2.1.83.3.1 C364的SysObjectID。所以除了最后一个通知之外的所有通知都来自192.168.197.159下的MFP,尽管最后6个通知TIdSNMP.Trap.Host包含值192.168.197.19。
答案 0 :(得分:2)
您描述的内容看起来像TIdSNMP.ReceiveTrap()
中的错误。它不是每次都调用TIdSNMP.Trap.Clear()
。它不应该随着时间的推移保留收到的陷阱的历史。我刚刚检查了Indy的SVN。如果您不想或不能升级您的Indy安装,一个简单的解决方法是在致电IdSNMP1.Trap.Clear()
之前致电IdSNMP1.ReceiveTrap()
:
while not Application.Terminated do begin
IdSNMP1.Trap.Clear(); // <-- add this
if IdSNMP1.ReceiveTrap() then begin
FormatTrap(IdSNMP1.Trap);
end;
Sleep(100);
Application.ProcessMessages();
end;
话虽如此,在UI点击处理程序中使用忙循环不是一个好主意。我建议您使用TTimer
代替:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages,
System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
Vcl.ExtCtrls, IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient, IdSNMP;
type
TForm1 = class(TForm)
Button2: TButton;
IdSNMP1: TIdSNMP;
Memo1: TMemo;
Timer1: TTimer;
procedure Button2Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
begin
Timer1.Interval := 100;
Timer1.Enabled := True;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
procedure FormatTrap(ASnmpInfo : TSnmpInfo);
var
i : integer;
begin
Memo1.Lines.BeginUpdate;
try
Memo1.Lines.Add('{');
Memo1.Lines.Add(Format('Host=%s, ', [ASnmpInfo.Host]));
Memo1.Lines.Add(Format('Port=%d, ', [ASnmpInfo.Port]));
Memo1.Lines.Add(Format('Enterprise=%s, ', [ASnmpInfo.Enterprise]));
Memo1.Lines.Add(Format('GenTrap=%d, ', [ASnmpInfo.GenTrap]));
Memo1.Lines.Add(Format('SpecTrap=%d, ', [ASnmpInfo.SpecTrap]));
Memo1.Lines.Add(Format('Version=%d, ', [ASnmpInfo.Version]));
Memo1.Lines.Add(Format('PDUType=%d, ', [ASnmpInfo.PDUType]));
Memo1.Lines.Add(Format('TimeTicks=%d, ', [ASnmpInfo.TimeTicks]));
Memo1.Lines.Add(Format('ID=%d, ', [ASnmpInfo.ID]));
Memo1.Lines.Add(Format('ErrorStatus=%d, ', [ASnmpInfo.ErrorStatus]));
Memo1.Lines.Add(Format('ErrorIndex=%d, ', [ASnmpInfo.ErrorIndex]));
Memo1.Lines.Add(Format('Community=%s, ', [ASnmpInfo.Community]));
Memo1.Lines.Add(Format('ValueCount=%d, ', [ASnmpInfo.ValueCount]));
for i := 0 to ASnmpInfo.ValueCount-1 do begin
Memo1.Lines.Add( Format('Value[%d]=%s, ', [i,ASnmpInfo.Value[i]]));
Memo1.Lines.Add( Format('ValueOID[%d]=%s, ', [i,ASnmpInfo.ValueOID[i]]));
Memo1.Lines.Add( Format('ValueType[%d]=%d, ', [i,ASnmpInfo.ValueType[i]]));
end;
Memo1.Lines.Add('}');
finally
Memo1.Lines.EndUpdate;
end;
end;
begin
IdSNMP1.Trap.Clear();
if IdSNMP1.ReceiveTrap() then begin
FormatTrap(IdSNMP1.Trap);
end;
end;
end.