Snmp4j 实战

2 篇文章 0 订阅

snmp4j中主要的类有 Snmp 、PDU、 CommunityTarget 、TransportMapping。下面分别介绍

1、Snmp

Snmp类:该类是SNMP4J中最为核心的类。负责SNMP报文的接受和发送。它提供了发送和接收PDU的方法,所有的PDU类型都可以采用同步或者异步的方式被发送。它有一个无参构造方法和3个重载构造方法。如下:

public Snmp() {
        this.pendingRequests = new Hashtable(50);
        this.asyncRequests = new Hashtable(50);
        this.timeoutModel = new DefaultTimeoutModel();
        this.notificationDispatcher = null;
        this.reportHandler = new Snmp.ReportProcessor();
        this.messageDispatcher = new MessageDispatcherImpl();
    }
public Snmp(TransportMapping transportMapping) {
        this();
        this.initMessageDispatcher();
        if (transportMapping != null) {
            this.addTransportMapping(transportMapping);
        }

    }

  public Snmp(MessageDispatcher messageDispatcher, TransportMapping transportMapping) {
        this.pendingRequests = new Hashtable(50);
        this.asyncRequests = new Hashtable(50);
        this.timeoutModel = new DefaultTimeoutModel();
        this.notificationDispatcher = null;
        this.reportHandler = new Snmp.ReportProcessor();
        this.messageDispatcher = messageDispatcher;
        this.messageDispatcher.addCommandResponder(this);
        if (transportMapping != null) {
            this.addTransportMapping(transportMapping);
        }

    }

public Snmp(MessageDispatcher messageDispatcher) {
        this.pendingRequests = new Hashtable(50);
        this.asyncRequests = new Hashtable(50);
        this.timeoutModel = new DefaultTimeoutModel();
        this.notificationDispatcher = null;
        this.reportHandler = new Snmp.ReportProcessor();
        this.messageDispatcher = messageDispatcher;
        this.messageDispatcher.addCommandResponder(this);
    }

2、PDU类和ScopedPDU类

该类是SNMP报文单元的抽象,其中PDU类适用于SNMPv1和SNMPv2c。ScopedPDU类继承于PDU类,适用于SNMPv3。

3、Target接口和CommunityTarget类以及UserTarget类

对应于SNMP代理的地址信息,包括IP地址和端口号(161)。其中Target接口适用于SNMPv1和SNMPv2c。CommunityTarget类实现了Target接口,用于SNMPv1和SNMPv2c这两个版本,UserTarget类实现了Target接口,适用于SNMPv3。

4、TransportMapping接口

该接口代表了SNMP4J所使用的传输层协议。这也是SNMP4J一大特色的地方。按照RFC的规定,SNMP是只使用UDP作为传输层协议的。而SNMP4J支持管理端和代理端使用UDP或者TCP进行传输。该接口有两个子接口。

Snmp、Target、PDU三者的关系

  Target代表远程设备或者远程实体、PDU代表管理端同Target通信的数据,Snmp就代表管理者管理功能(其实就是数据的收发)的具体执行者。

  打个比方:Target就是你远方的恋人,PDU就是你们之间传递的情书、而Snmp就是负责帮你寄信收信的邮差。

2、SNMP4J的两种消息发送模式

SNMP4J支持两种消息发送模式:同步发送模式和异步发送模式

  同步发送模式也称阻塞模式当管理端发送出一条消息之后,线程会被阻塞,直到收到对方的回应或者时间超时。同步发送模式编程较为简单,但是不适用于发送广播消息。

  异步发送模式也称非阻塞模式。当程序发送一条消息之后,线程将会继续执行,当收到消息的回应的时候,程序会对消息作出相应的处理。要实现异步发送模式,需要实例化一个实现了ResponseListener接口的类的对象。ResponseListener接口中有一个名为onResponse的函数。这是一个回调函数,当程序收到响应的时候,会自动调用该函数。由该函数完成对响应的处理。

3、使用snmp4j步骤

  (1)初始化

  • 明确SNMP在传输层所使用的协议  一般情况下,我们都使用使用UDP协议作为SNMP的传输层协议,所以我们需要实例化的是一个DefaultUdpTransportMapping接口对象;

  • 实例化一个snmp对象   在此过程中,我们需要将1中实例化的DefaultUdpTransportMapping接口的对象作为参数,穿snmp类的构造函数中。另外,如果实现的SNMPv3协议,我们还需要设置安全机制,添加安全用户等等;

  • 监听snmp消息  在此,我们可以调用刚刚实例化的DefaultUdpTransportMapping的接口对象的listen方法,让程序监听snmp消息;

(2)构造发送目标

 如果实现的是SNMPv2c或者说SNMPv1,需要实例化一个CommunityTarget对象。如果实现的是SNMPv3程序,则需要实例化一个UserTarget对象。

  之后,我们还需要对实例化的对象做一些设置。如果是CommunityTarget的对象,则需要设置使用的Snmp版本,重传时间和等待时延。如果是UserTarget对象,我们不仅需要设置版本、重传时间、等待时延,还需要设置安全级别和安全名称。

(3)构造发送报文

如果发送的是SNMPv2c或者说SNMPv1的报文,我们需要实例化一个PDU类的对象。如果发送的是SNMPv3的报文,我们则需要实例化一个ScopedPDU类的对象。之后,我们还需要生成一个OID对象,其中包含了我们所需要获取的SNMP对象在MIB库中的ID。然后我们需要将OID和之前生成的PDU对象或者是ScopedPDU对象绑定,并且设置PDU的报文类型(五种SNMP报文类型之一)。

(4)构造响应监听对象(异步模式)

当使用异步模式的时候,我们需要实例化一个实现了ResponseListener接口的对象,作为响应消息的监听对象。在构造该对象的过程中,我们需要重写ResponseListener的OnResponse函数,该函数是一个回调函数,用来处理程序收到响应后的一些操作。

(5)发送消息

当所有上述操作都设置完毕之后,就可以发送消息了。同步模式和异步模式发送消息调用的函数名字均为send,但是两个函数所需参数不一样。同步模式的参数仅为2和3中构造的目标对象和报文对象,而异步模式还需要上述的构造的监听对象。

同步模式发送消息后便等待响应的到达,到达之后会返回一个ResponseEvent对象,该对象中包含了响应的相应信息。

异步模式发送消息之后便会继续执行,当收到响应消息时便会调用监听对象的OnResponse函数。该函数中的语句便是我们对响应的处理。

具体代码如下:

package demo1;

import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.*;
import org.snmp4j.transport.DefaultUdpTransportMapping;

import java.io.IOException;


public class SNMPdemo {


    public static void main(String[] args) {
        Address address = GenericAddress.parse("udp:192.168.103.177/161");
        CommunityTarget communityTarget = new CommunityTarget();
        communityTarget.setCommunity(new OctetString("public"));
        communityTarget.setAddress(address);
        communityTarget.setTimeout(10000);
        communityTarget.setVersion(SnmpConstants.version2c);
        PDU pduSet = createSetPDU();
        PDU pduGet = createGetPDU();

        sendPDU(pduSet, communityTarget);
        sendPDU(pduGet, communityTarget);
    }

    //1.3.6.1.2.1.1.5.0
    public static PDU createSetPDU(){
        PDU pdu = new PDU();
        pdu.setType(PDU.SET);
        VariableBinding vb = new VariableBinding(new OID("1.3.6.1.2.1.1.1.0"), new OctetString("testname"));
        pdu.add(vb);
        return pdu;
    }
    //
    public  static PDU createGetPDU(){
        PDU pdu = new PDU();
        pdu.setType(PDU.GET);
        VariableBinding vb = new VariableBinding(new OID("1.3.6.1.2.1.1.1.0"));
        pdu.add(vb);
        return pdu;
    }
    //
    public static  void sendPDU(PDU pdu, CommunityTarget communityTarget){
        try {
            TransportMapping transportMapping = new DefaultUdpTransportMapping();
            Snmp snmp = new Snmp(transportMapping);
            snmp.listen();
            ResponseEvent responseEvent = snmp.send(pdu, communityTarget);
            PDU pduResponse = responseEvent.getResponse();
            if(null != pduResponse){
                System.out.println("size = " + pduResponse.size());
                for(int i =0;i<pduResponse.size();i++){
                    VariableBinding variableBinding = pduResponse.get(i);
                    Variable variable = variableBinding.getVariable();
                    System.out.println("variable = " + variable);
                }
                System.out.println("error : " + pduResponse.getErrorStatusText());
            }else {
                System.out.println("Time out ...");
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
    }
}

运行结果:

Time out ...
size = 1
variable = Hardware: Intel64 Family 6 Model 158 Stepping 9 AT/AT COMPATIBLE - Software: Windows Version 6.3 (Build 17134 Multiprocessor Free)
error : Success

Process finished with exit code 0

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值