以前从未接触过snmp协议,昨天在工作中接到一个需求,HTTP接收数据,SNMP转发出去。于是上网查阅了相关文档,总结的不是很详细,于是自己整理一下,方便以后查阅使用。
1、首先引入相关依赖
<!--snmp 相关-->
<dependency>
<groupId>org.snmp4j</groupId>
<artifactId>snmp4j</artifactId>
<version>2.5.2</version>
</dependency>
2、使用snmp发送数据主要有一下4个大步骤:
初始化Snmp,创建snmp对象;
创建你要发送数据的接收方,也就是target对象;
创建PDU对象,里面包含要发送的报文数据,可以是自定义对象;
发送数据报文,获取结果。
3、下面逐个演示具体代码实现
snmp有3个版本,涉及到的类有MPv1、MPv2和MPv3分别对应snmp版本v1、v2c和v3。
初始化snmp对象
public static void initSnmp() throws IOException {
MessageDispatcher messageDispathcher=new MessageDispatcherImpl();
//增加三种处理模型
messageDispathcher.addMessageProcessingModel(new MPv1());
messageDispathcher.addMessageProcessingModel(new MPv2c());
//添加snmpv3版本
OctetString localEngineID = new OctetString(MPv3.createLocalEngineID());
USM usm = new USM(SecurityProtocols.getInstance().addDefaultProtocols(), localEngineID, 0);
UsmUser user = new UsmUser(new OctetString("SNMPV3"), AuthSHA.ID, new OctetString("authPassword"),
PrivAES128.ID, new OctetString("privPassword"));
usm.addUser(user.getSecurityName(),user);
messageDispathcher.addMessageProcessingModel(new MPv3(usm));
//创建transportMapping
//UdpAddress sourceAddr=(UdpAddress)GenericAddress.parse("udp:10.73.140.49/161");
TransportMapping<?> transportMapping=new DefaultUdpTransportMapping();
//创建snmp
snmp=new Snmp(messageDispathcher,transportMapping);
//开启监听
transportMapping.listen();
}
创建target对象
v1,v2c版本创建CommunityTarget对象,v3创建UserTarget对象,同时snmpV3需要设置安全级别和安全名称,其中安全名称是创建snmp指定user设置的new OctetString(“SNMPV3”)
针对snmpv1和snmpv2c需要设置团体名。target.setCommunity()
private static Target createTarget() {
Target target=null;
if(!(snmpVersion==SnmpConstants.version3 || snmpVersion == SnmpConstants.version2c
|| snmpVersion == SnmpConstants.version1)) {
logger.error("snmp version is illegal");
return target;
}
//获取目标地址
String url=getConfig("snmp.target.address");
UdpAddress udpAddr=null;
if(url!=null && !url.trim().equals("") && !url.trim().isEmpty()) {
udpAddr=(UdpAddress)GenericAddress.parse(url);
}
else {
throw new BizException("there isn't the config file or legal target parameter");
}
if(snmpVersion==SnmpConstants.version3) {
target=new UserTarget();
//snmpV3需要设置安全级别和安全名称,其中安全名称是创建snmp指定user设置的new OctetString("SNMPV3")
target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
target.setSecurityName(new OctetString("SNMPV3"));
}
else {
//snmpV1和snmpV2需要指定团体名名称
target=new CommunityTarget();
((CommunityTarget)target).setCommunity(new OctetString(community));
/*if(snmpVersion==SnmpConstants.version2c) {
target.setSecurityModel(SecurityModel.SECURITY_MODEL_SNMPv2c);
}*/
}
target.setVersion(snmpVersion);
//必须指定,没有设置就会报错
target.setAddress(udpAddr);
target.setRetries(5);
target.setTimeout(3000);
return target;
}
创建PDU单元报文
通过VariableBinding将OID和数据绑定,每一个oid对应一个属性。
v3版本使用ScopedPDU对象,v1,v2c使用PDUv1对象
public static PDU createPDU(WarningData warningData) {
PDU pdu=null;
if(snmpVersion==SnmpConstants.version3) {
pdu=new ScopedPDU();
}else {
pdu=new PDUv1();
}
pdu.setType(type);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if(warningData.getSysUpTime() != null){
pdu.add(new VariableBinding(SnmpConstants.sysUpTime,
new OctetString(Base64.getBase64(df.format(new Date())))));
}
if(warningData.getSnmpTrapOid()!=null) {
pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID,
new OctetString(Base64.getBase64(warningData.getSnmpTrapOid()))));
}
if(warningData.getId() != null){
pdu.add(new VariableBinding(new OID(WarningData.Oid.ID.code)
,new OctetString(Base64.getBase64(String.valueOf(warningData.getId())))));
}
if(warningData.getPoolId() != null){
pdu.add(new VariableBinding(new OID(WarningData.Oid.POOLID.code)
,new OctetString(Base64.getBase64(warningData.getPoolId()))));
}
if(warningData.getSerialNumber()!=null) {
pdu.add(new VariableBinding(new OID(WarningData.Oid.SERIALNUMBER.code)
,new OctetString(Base64.getBase64(String.valueOf(warningData.getSerialNumber())))));
}
if(warningData.getAlarmType() != null){
pdu.add(new VariableBinding(new OID(WarningData.Oid.ALARMTYPE.code)
,new OctetString(Base64.getBase64(warningData.getAlarmType()))));
}
if(warningData.getAlarmTitleId()!=null) {
pdu.add(new VariableBinding(new OID(WarningData.Oid.ALARMTITLEID.code)
,new OctetString(Base64.getBase64(warningData.getAlarmTitleId()))));
}
if(warningData.getAlarmTitle() != null){
pdu.add(new VariableBinding(new OID(WarningData.Oid.ALARMTITLE.code)
,new OctetString(Base64.getBase64(warningData.getAlarmTitle()))));
}
if(warningData.getAlarmContent() != null){
pdu.add(new VariableBinding(new OID(WarningData.Oid.ALARMCONTENT.code)
,new OctetString(Base64.getBase64(warningData.getAlarmContent()))));
}
if(warningData.getAlarmLevel() != null){
pdu.add(new VariableBinding(new OID(WarningData.Oid.ALARMLEVEL.code)
,new OctetString(Base64.getBase64(String.valueOf(warningData.getAlarmLevel())))));
}
if(warningData.getAlarmTime() != null){
pdu.add(new VariableBinding(new OID(WarningData.Oid.ALARMTIME.code)
,new OctetString(Base64.getBase64(String.valueOf(warningData.getAlarmTime())))));
}
if(warningData.getObjectId() != null){
pdu.add(new VariableBinding(new OID(WarningData.Oid.OBJECTID.code)
,new OctetString(Base64.getBase64(warningData.getObjectId()))));
}
return pdu;
}```
**发送数据**
public static Boolean snmpGet(WarningData warningData) {
//1、初始化snmp,并开启监听
try {
initSnmp();
} catch (IOException e) {
logger.info("初始化snmp出错" + e.getMessage());
e.printStackTrace();
}
//2、创建目标对象
Target target=createTarget();
//3、创建报文
PDU pdu=createPDU(warningData);
logger.info("-------> 发送PDU报文<-------");
//4、发送报文,并获取结果
ResponseEvent responseEvent=null;
if(pdu!=null) {
try {
responseEvent = snmp.send(pdu, target);
if(responseEvent == null || responseEvent.getResponse() == null) {
failedPdus.add(pdu);
return false;
}
else {
@SuppressWarnings("unchecked")
Vector<VariableBinding> recVBs =(Vector<VariableBinding>) responseEvent.getResponse()
.getVariableBindings();
for (int i = 0; i < recVBs.size(); i++) {
VariableBinding recVB = recVBs.elementAt(i);
logger.info(recVB.getOid() + " : " + recVB.getVariable());
}
successPdus.add(pdu);
return true;
}
} catch (IOException e) {
e.printStackTrace();
}
}
// logger.info("返回结果:共{}条,成功发送{}条,发送失败{}条",
// warningDatas.size(),successPdus.size(),failedPdus.size());
if(snmp!=null) {
try {
snmp.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return true;
}