snmp中告警的接收可以使用jdmk中的SnmpTrapListener,采用jdmk接收snmp trap的方式如下,先定义接收的线程,再用继承自SnmpTrapListener的类处理snmp的trap。详细内容见代码。
代码如下:
public class SnmpListener {
/**
* Main entry point.
*/
public static void main(String argv[]) {
try {
//创建一个DaemonTaskServer处理snmp的traps
//你也可以不用DaemonTaskServer,但使用DaemonTaskServer
//处理收到的PDU单元,可以更快的腾出来用于接收trap的socket,
//这样可以减少丢包(trap是udp包)
//把DaemonTaskServer的线程设置为NORM_PRIORITY,这样
//trap接收的线程可以优先于trap处理的线程
final DaemonTaskServer taskServer = new DaemonTaskServer();
taskServer.start(Thread.NORM_PRIORITY);
//为snmp的trap包创建分配器(SnmpEventReportDispatcher)和监听器
//SnmpEventReportDispatcher做为一个线程运行,并且在指定的端口监听traps
final SnmpEventReportDispatcher trapAgent =
new SnmpEventReportDispatcher(Integer.parseInt("8085")+1,
null,taskServer,null);
//把TrapListenerImpl作为snmp trap的监听器
// TrapListenerImpl处理trap pdu包
trapAgent.addTrapListener(new TrapListenerImpl());
final Thread trapThread = new Thread(trapAgent);
trapThread.setPriority(Thread.MAX_PRIORITY);
trapThread.start();
Thread.sleep(4000);
println("\n>> Press <Enter> if you want to stop" +
" this SNMP manager.\n");
java.lang.System.in.read();
//stop the SnmpEventReportDispatcher.
trapAgent.close();
taskServer.terminate();
java.lang.System.exit(0);
} catch(Exception e) {
java.lang.System.err.println("AsyncManager::main: "+
"Exception occurred:" + e );
e.printStackTrace();
}
}
实际处理trap的pdu包的类:
public class TrapListenerImpl implements SnmpTrapListener {
public void processSnmpTrapV1(SnmpPduTrap trap) {
println("NOTE: TrapListenerImpl received trap :");
println("\tGeneric " + trap.genericTrap);
println("\tSpecific " + trap.specificTrap);
println("\tTimeStamp " + trap.timeStamp);
println("\tAgent adress " + trap.agentAddr.stringValue());
}
public void processSnmpTrapV2(SnmpPduRequest trap) {
println("NOTE: Trap V2 not of interest !!!");
}
public void processSnmpTrapV3(SnmpScopedPduRequest trap) {
println("NOTE: TrapListenerImpl received trap V3:");
println("\tContextEngineId : " +
SnmpEngineId.createEngineId(trap.contextEngineId));
println("\tContextName : " + new String(trap.contextName));
println("\tVarBind list :");
for(int i = 0; i < trap.varBindList.length; i++)
println("oid : " + trap.varBindList[i].getOid() + " val : " +
trap.varBindList[i].getSnmpValue());
}
/**
* print/println stuff...
*/
private final static void println(String msg) {
java.lang.System.out.println(msg);
}
private final static void print(String msg) {
java.lang.System.out.print(msg);
}
}
顺便发一段法送SnmpTrapV1的代码:
public static void main(String args[]) {
try {
// Bind the adaptor. By default port 161 is used.
// For the example, we are going to use a on standard port.
//
// If you wish to use the standard SNMP ports, just comment
// out the following line:
// port = 8085;
//
int port = 8085;
snmpAdaptor = new SnmpAdaptorServer(port);
println("NOTE: SNMP Adaptor is bound on port " + port);
// Start the adaptor.
//
snmpAdaptor.start();
// Send a coldStart SNMP Trap.
//
print("NOTE: Sending a coldStart SNMP trap to"
+ " each destination defined in the ACL file...");
snmpAdaptor.setTrapPort(new Integer(port + 1));
snmpAdaptor.snmpV1Trap(0, 0, null);
println("v1 Done.");
} catch (Exception e) {
e.printStackTrace();
}
}
使用snmpAdaptor.snmpV1Trap(0, 0, null)可以像目的端(接收snmp trap的程序)发送一个trap。