`
jl19861101
  • 浏览: 29799 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Snmp4j编程简介之三:Snmp

阅读更多

Snmp4j编程简介之三:Snmp
Class Snmp

java.lang.Object
org.snmp4j.Snmp
All Implemented Interfaces:
java.util.EventListener, CommandResponder, Session
snmp类是SNMP4J的核心,它提供了发送和接收SNMP PDUs的方法,所有的SNMP PDU 类型都可以采用同步或者异步的方式被发送。

Snmp采用独立的传输协议,通过TransportMapping 接口调用addTransportMapping(TransportMapping transportMapping) 方法或者采用默认的构造函数来实现传输映射,以此来实现信息的传输。

下面的代码片段是采用UDP传输方式来实现一个SNMPv3的SNMP session :

Java代码
Address targetAddress = GenericAddress.parse("udp:127.0.0.1/161");
TransportMapping transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
USM usm = new USM(SecurityProtocols.getInstance(),
new OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
transport.listen();

Address targetAddress = GenericAddress.parse("udp:127.0.0.1/161");
TransportMapping transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
USM usm = new USM(SecurityProtocols.getInstance(),
new OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
transport.listen();

如何实现SNMPv3信息的同步发送,下面举例说明:


Java代码
// add user to the USM
snmp.getUSM().addUser(new OctetString("MD5DES"),
new UsmUser(new OctetString("MD5DES"),
AuthMD5.ID,
new OctetString("MD5DESUserAuthPassword"),
PrivDES.ID,
new OctetString("MD5DESUserPrivPassword")));
// create the target
UserTarget target = new UserTarget();
target.setAddress(targetAddress);
target.setRetries(1);
target.setTimeout(5000);
target.setVersion(SnmpConstants.version3);
target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
target.setSecurityName(new OctetString("MD5DES"));

// create the PDU
PDU pdu = new ScopedPDU();
pdu.add(new VariableBinding(new OID("1.3.6")));
pdu.setType(PDU.GETNEXT);

// send the PDU
ResponseEvent response = snmp.send(pdu, target);
// extract the response PDU (could be null if timed out)
PDU responsePDU = response.getResponse();
// extract the address used by the agent to send the response:
Address peerAddress = response.getPeerAddress();
An asynchronous SNMPv1 request is sent by the following code:

// setting up target
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setAddress(targetAddress);
target.setRetries(2);
target.setTimeout(1500);
target.setVersion(SnmpConstants.version1);
// creating PDU
PDU pdu = new PDU();
pdu.add(new VariableBinding(new OID(new int[] {1,3,6,1,2,1,1,1})));
pdu.add(new VariableBinding(new OID(new int[] {1,3,6,1,2,1,1,2})));
pdu.setType(PDU.GETNEXT);
// sending request
ResponseListener listener = new ResponseListener() {
public void onResponse(ResponseEvent event) {
// Always cancel async request when response has been received
// otherwise a memory leak is created! Not canceling a request
// immediately can be useful when sending a request to a broadcast
// address.
((Snmp)event.getSource()).cancel(event.getRequest(), this);
System.out.println("Received response PDU is: "+event.getResponse());
}
};
snmp.sendPDU(pdu, target, null, listener);

//Traps (notifications) and other SNMP PDUs can be received by adding the folling code to the first code snippet above:
CommandResponder trapPrinter = new CommandResponder() {
public synchronized void processPdu(CommandResponderEvent e) {
PDU command = e.getPDU();
if (command != null) {
System.out.println(command.toString());
}
}
};
snmp.addCommandResponder(trapPrinter);



Version:
1.8
Author:
Frank Fock
translate:avery_leo

// add user to the USM
snmp.getUSM().addUser(new OctetString("MD5DES"),
new UsmUser(new OctetString("MD5DES"),
AuthMD5.ID,
new OctetString("MD5DESUserAuthPassword"),
PrivDES.ID,
new OctetString("MD5DESUserPrivPassword")));
// create the target
UserTarget target = new UserTarget();
target.setAddress(targetAddress);
target.setRetries(1);
target.setTimeout(5000);
target.setVersion(SnmpConstants.version3);
target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
target.setSecurityName(new OctetString("MD5DES"));

// create the PDU
PDU pdu = new ScopedPDU();
pdu.add(new VariableBinding(new OID("1.3.6")));
pdu.setType(PDU.GETNEXT);

// send the PDU
ResponseEvent response = snmp.send(pdu, target);
// extract the response PDU (could be null if timed out)
PDU responsePDU = response.getResponse();
// extract the address used by the agent to send the response:
Address peerAddress = response.getPeerAddress();
An asynchronous SNMPv1 request is sent by the following code:

// setting up target
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setAddress(targetAddress);
target.setRetries(2);
target.setTimeout(1500);
target.setVersion(SnmpConstants.version1);
// creating PDU
PDU pdu = new PDU();
pdu.add(new VariableBinding(new OID(new int[] {1,3,6,1,2,1,1,1})));
pdu.add(new VariableBinding(new OID(new int[] {1,3,6,1,2,1,1,2})));
pdu.setType(PDU.GETNEXT);
// sending request
ResponseListener listener = new ResponseListener() {
public void onResponse(ResponseEvent event) {
// Always cancel async request when response has been received
// otherwise a memory leak is created! Not canceling a request
// immediately can be useful when sending a request to a broadcast
// address.
((Snmp)event.getSource()).cancel(event.getRequest(), this);
System.out.println("Received response PDU is: "+event.getResponse());
}
};
snmp.sendPDU(pdu, target, null, listener);

//Traps (notifications) and other SNMP PDUs can be received by adding the folling code to the first code snippet above:
CommandResponder trapPrinter = new CommandResponder() {
public synchronized void processPdu(CommandResponderEvent e) {
PDU command = e.getPDU();
if (command != null) {
System.out.println(command.toString());
}
}
};
snmp.addCommandResponder(trapPrinter);


Version:
1.8
Author:
Frank Fock
translate:avery_leo

Snmp类提供了一套有关Snmp的功能接口。具体来讲,就是发送、接受、创建Snmp消息。
一个Snmp对象是一个Session,而在Snmp4j中,一个Session可以同多个远程设备通信。

(1) Snmp、Target、PDU三者的关系
Target代表远程设备或者远程实体、PDU代表管理端同Target通信的数据,Snmp就代表管理者管理功能(其实就是数据的收发)的具体执行者。
打个比方:Target就是你远方的恋人,PDU就是你们之间传递的情书、而Snmp就是负责帮你寄信收信的邮差。

(2)Snmp收发数据的两种方式
Snmp可以同步、也可异步收发数据。详细见代码示例说明。

(3)Snmp与传输层协议
Snmp可以定制传输层协议,一般选择udp,也可以选择tcp。详细见代码示例说明。

(4)Snmp与Usm
创建Snmp用来发送Snmpv3版本的消息时候,一般还要创建USM,将它添加至安全模型管理器(SecriryModels)中,同时还需要向Usm中添加相应的USM用户(UsmUser)。详细见代码示例说明。

代码示例:(摘自Snmp4j的API文档)

(1)创建Snmp
1)使用UDP传输协议

TransportMapping transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport); 2)使用TCP传输协议

TransportMapping transport = new DefaultTcpTransportMapping();
snmp = new Snmp(transport); 3)创建用于Snmpv3的Snmp

// 创建Snmp
TransportMapping transport =
new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(transport);
if (version == SnmpConstants.version3) {
byte[] localEngineID =
((MPv3)snmp.getMessageProcessingModel(MessageProcessingModel.MPv3)).createLocalEngineID();
// 创建USM
USM usm = new USM(SecurityProtocols.getInstance(),
new OctetString(localEngineID), 0);
// 将USM添加至安全模式管理器中
// 安全模型管理器采用了单例模式,它内部可以维护为3个安全模型,分别对应Snmp三个版本
SecurityModels.getInstance().addSecurityModel(usm);
snmp.setLocalEngine(localEngineID, 0, 0);
// 添加用户
snmp.getUSM().addUser(securityName,new UsmUser(securityName,authProtocol,
authPassphrase,privProtocol,privPassphrase));
}(2)同步收发消息

import org.snmp4j.*;
...
Snmp snmp = new Snmp(new DefaultUdpTransportMapping());
...
ResponseEvent response = snmp.send(requestPDU, target);
if (response.getResponse() == null) {
// request timed out
...
}else {
System.out.println("Received response from: "+
response.getPeerAddress());
// dump response PDU
System.out.println(response.getResponse().toString());
}(3)异步收发消息

import org.snmp4j.*;
import org.snmp4j.event.*;
...
Snmp snmp = new Snmp(new DefaultUdpTransportMapping());
...
// 增加监听器
ResponseListener listener = new ResponseListener() {
public void onResponse(ResponseEvent event) {
PDU response = event.getResponse();
PDU request = event.getRequest();
if (response == null) {
System.out.println("Request "+request+" timed out");
} else {
System.out.println("Received response "+response+" on request "+
request);
}
};
snmp.sendPDU(request, target, null, listener);
...(4)实现trap
实现trap需要三步:
1)创建Snmp;
2)对于listen()使处于网络监听(实际上是同于网络编程中的Socket监听);
3)实现CommandResponder接口的监听器,并且调用Snmp.addCommandResponder(CommandResponder)注册监听器。

import org.snmp4j.*;
import org.snmp4j.smi.*;
import org.snmp4j.mp.SnmpConstants;
...
TransportMapping transport =
new DefaultUdpTransportMapping(new UdpAddress("0.0.0.0/161"));
Snmp snmp = new Snmp(transport);
if (version == SnmpConstants.version3) {
byte[] localEngineID =
((MPv3)snmp.getMessageProcessingModel(MessageProcessingModel.MPv3)).createLocalEngineID();
USM usm = new USM(SecurityProtocols.getInstance(),
new OctetString(localEngineID), 0);
SecurityModels.getInstance().addSecurityModel(usm);
snmp.setLocalEngine(localEngineID, 0, 0);
// Add the configured user to the USM
...
}
// 注册命令响应监听器
snmp.addCommandResponder(this);
transport.listen();
...
// 实现CommandResponder接口
public synchronized void processPdu(CommandResponderEvent e) {
PDU command = e.getPdu();
if (command != null) {
...
}
}
总结
Snmp内含了一个消息分发器,消息分发器中内含了处理网络的线程,在使用完后最好调用close(),将其资源回归处理。
掌握了上面所说的三个概念,基本上可以使用Snmp4j编写Snmp的程序了。
有关Snmp4j编程最好也最详细的资料:API文档和源代码。关于使用Snmp4j编写Snmp程序的例子,多线程的例子可以参看源代码中:org.snmp4j.test包下的MultiThreadedTrapReceiver.java,完整的例子可以参看 org.snmp4j.tools.console包下的SnmpRequest(一个命令行的Snmp管理器)。
不过,要想快速和深入掌握Snmp编程,最好的办法一定是先弄懂Snmp协议,这方面的资料最权威的就是RFC协议了。

分享到:
评论

相关推荐

    snmp4j编程简介.doc

    snmp4j编程简介.doc

    Snmp4j 编程入门.doc

    Snmp4j 编程入门 doc

    基于SNMP4J的SNMP操作实现代码

    利用snmp4j实现snmp协议三个版本的get、getnext、set、trap操作的源代码,帮助你快速上手snmp协议的实现

    使用Java进行SNMP编程-SNMP4J-代码实例

    使用Java进行SNMP编程-SNMP4J-代码实例,代码实例实现了GET, GETNEXT, GETBULK, Walk, SET操作; 提供于做服务器监控的朋友;

    snmp4j-1.7.6a.zip_SNMP4J例子_java snmp编程_package_snmp in java _snm

    Java SNMP Package:这是一个实现了SNMP协议的Java包.它提供对基本的SNMP客户端与在SNMP版本1和2中定义的代理操作的支持.这个包提供了一种机制用于取得与设置SNMP对象标识(OID:object identifier)值通过一个简单的...

    SNMP探测器 关于SNMP的Java编程

    使用SNMP4J写的SNMP探测工具。 有详尽的SNMP4J编程范例

    SNMP4j帮助文件

    该帮助用于Java开发snmp协议应用的编程有极大的帮助。使开发必备的手册之一

    snmp4j开发包,强烈推荐

    非常好的开发包,完整封装了v1,v2,v3,详细实例,snmp编程利器

    snmp4j-agent-2.3.2-distribution.zip_JAVA SNMP监控_SNMP 监控_snmp监控

    用snmp4j实现的agent,代码比较多,但是很值得一看,尤其是对于要用SNMP监控信息的编程者,可以仔细研究一下里面的代码.-Achieved with snmp4j agent, code more,

    snmp4j.jar的使用情况

    这里包含常见的snmp的使用,包括消息的发送,消息的响应和读取MIB以及存取CPU等的状态,对SNMP编程很有帮助

    SNMPv2Test.zip_SNMP编程_Java_

    用snmp4j的API实现的监控TCP连接状态的小程序,网上关于snmp4j的代码太少了,大部分都是c和c++的,希望对有需要的人有帮助

    snmp-blog-master.zip_中间件编程_Java_

    Introduction to snmp4j

    论文研究 - 省级气象观测数据传输综合监测模型的设计与应用

    该系统使用Java作为编程语言,并遵循MVC规范和敏捷开发概念,集成了J2EE,Hibernate,Quartz,Snmp4j和Slf4j框架,并使用Oracle数据库作为数据存储载体。 系统开发使用四项关键技术,包括简单的网络管理协议,网络...

    java开源包4

    BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步输出框架 AsynWriter 一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用...

    java开源包1

    BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步输出框架 AsynWriter 一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用...

    java开源包11

    BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步输出框架 AsynWriter 一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用...

    java开源包2

    BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步输出框架 AsynWriter 一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用...

    java开源包3

    BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步输出框架 AsynWriter 一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用...

    java开源包6

    BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步输出框架 AsynWriter 一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用...

Global site tag (gtag.js) - Google Analytics