一、SNMP简介
简单网络管理协议(SNMP,Simple Network Management Protocol)也是基于C/S的模型,它实现了这样一种功能,当管理端需要获取被管理端的一个状态信息时,管理端就发送一个获取指令给被管理端,被管理端收到此指令后把管理端要获取的信息封装成报文后返回给管理端;当管理端需要修改被管理端上的一些配置参数时,管理端就发送一个修改指令给被管理端,被管理端收到后修改相应的配置,如果修改成功,则返回修改成功的信息给管理端,如果未修改成功,则返回相应的错误信息给管理端;如果被管理端自己知道自己发生了故障,那它就主动发生一个消息给管理端,说明自己哪里出现了故障。
SNMP主要有三个版本,SNMPv1、SNMPv2c、SNMPv3。SNMPv1版是最始的版本,实现简单,存在较多安全缺陷,SNMPv2c版本质上与SNMPv1相同,只是在前一版上在功能上做了加强,并增加了getbulk操作等,还增加了一些更直观的错误响应,SNMPv3版解决了前两个版本在安全上的问题,采用了USM和VACM技术,增加了更强的认证机制。但这三个版中使用最多的依然是SNMPv1版,在现在各产家的IT设备中,有部分根本就不支持SNMPv3。
二、snmp4j简介
SNMP4J是一个用Java来实现SNMP(简单网络管理协议)协议的开源项目.它支持以命令行的形式进行管理与响应。SNMP4J是纯面向对象设计与SNMP++(用C++实现SNMPv1/v2c/v3)相类似。
SNMP4J API 提供以下下特性:
支持MD5和SHA验证,DES、3DES、AES128、AES192和AES256加密的SNMPv3。
支持MPv1,MPv2C和MPv3,带执行的可阻塞的 信息处理模块。
全部PDU格式。
可阻塞的传输拓扑。支持UPD、TCP、TLS 。
可阻塞的超时模块。
同步和异步请求。
命令发生器以及命令应答器的支持。
基于Apache license的开源免费。
JAVA 1.4.1或更高版本(2.0或更高版本需要jdk1.6及以上的支持)。
基于LOG4J记录日志。
使用GETBULK实现Row-based的有效的异步表格获取。
支持多线程。
三、SNMP核心类型简介
下图描述了SNMP4J最重要的核心类之间的关系,其中蓝色箭头代表向远程SNMP实体(目标)发送的请求,红色代表远程SNMP实体发送给当前SNMP会话的请求
SNMP类,一般称为SNMP4J会话,是整个框架的核心,用户代码主要和它进行交互.snmp4j向外部SNMP实体发送请求的过程如下:
1.用户代码(调用者)通过Snmp.send()方法发起请求
2.TransportMapping组件通过底层的TCP或者UDP协议将请求传输出去
3.请求,应答的载体均是PDU,对应了SNMP报文
4.Target代表远程SNMP实体,持有它的地址,身份,SNMP版本等信息
5.对于同步请求,应答直接返回给调用程序,对于异步请求,应答通过ResponseListener回调,ResponseListener在祈求发送异步请求时,作为方法参数注册  SNMP4J接收外部SNMP实体的请求,并进行处理的过程如下:
1) snmp4j监听(通过TransportMapping)外部SNMP报文,并转为PDU类型
2) MessageDispatcher负责将PDU转发给(回调)合适的CommandResponder,自定义CommandResponder可以注册到SNMP会话
3) CommandResponder负责处理请求PDU,可选的,给出一个应答PDU
四、snmp使用示例
private Snmp snmp = null;
private Address targetAddress = null;
TransportMapping transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
transport.listen();
//开始监听请求,监听端口在snmp4j框架中设置
// target CommunityTarget target = new CommunityTarget(); target.setCommunity(new OctetString("public"));
// public target.setAddress(targetAddress);
//设置重传次数
target.setRetries(2);
//设置每次发送超时时间
target.setTimeout(1500); // 1.5秒
target.setVersion(SnmpConstants.version1);
pdu.setType(PDU.GET);
//代理PDU响应
ResponseEvent respEvnt;
respEvnt = snmp.send(pdu,target); //发送数据
// parse Response
if (respEvnt != null && respEvnt.getResponse() != null) {
Vector<VariableBinding> recVBs = (Vector<VariableBinding>) respEvnt.getResponse().getVariableBindings();
for (int i = 0; i < recVBs.size(); i++) {
VariableBinding recVB = recVBs.elementAt(i);
System.out.println(recVB.getOid() + " : " + recVB.getVariable());
}
}
...