org.snmp4j包

没事练练翻译,想看的凑合着看吧,原文http://www.snmp4j.org/doc/index.html

org.snmp4j

提供了创建、发送和接收SNMP消息的类和接口。

org.snmp4j包中的类可以用来创建、发送和接收SNMPv1/v2c/v3消息。一个SNMP消息是由协议头和PDU(协议数据单元)构成。这个包主要包含三组类和接口:

  • 用于创建SNMP消息和target的类
  • 用于发送(生成命令)SNMP消息的类
  • 用于分发(命令响应)SNMP消息的类

下面的UML包图描述了SNMP4J API的核心的包之间的依赖关系。用户通常只用到org.snmp4j包和org.snmp4j.smi包。

org.snmp4j包图

下面的UML类图展示了org.snmp4j包中的最重要的类以及类之间的关系(不包含和其他包之间的关系)

org.snmp4j类图

SNMP 消息和Targets

为了和远程系统交换SNMP消息,系统必须能被识别,并且为消息交换指定重发和超时策略。SNMP4J通过创建一个用于SNMP协议的Target实例来确定一个远程系统。

  • 对于SNMPv1SNMPv2c,采用表示社团信息的CommunityTarget类来指定Target接口中定义的地址、重发及超时策略信息。
  • 对于SNMPv3需要用到UserTarget类。它继承自SecureTarget抽象类,用来提供下述的基于用户的安全模型(USM)的用户信息:security name, security level, security model(例如:USM),authoritative engine ID

一个SNMP消息由消息的数据包:SNMP协议数据单元(PDU)和消息头构成。简单来说,SNMP4J中消息头由Target实例表示,PDU由以下类表示:

  • PDUv1 (SNMPv1)
  • PDU (SNMPv2c)
  • ScopedPDU (SNMPv3)

因此,为了通过SNMP4J发送一个SNMP消息必须创建一个PDU实例和一个Target实例。

PDU 实例

  • SNMPv1/v2c GETNEXT PDU

·          

·         import org.snmp4j.PDU;

·         import org.snmp4j.smi.*;

·         ...

·         PDU pdu = new PDU();

·         pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.1"))); // sysDescr

·         pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.2.1"))); // ifNumber

·         pdu.setType(PDU.GETNEXT);

·         ...

   

  • SNMPv3 GETBULK PDU

·          

·         import org.snmp4j.ScopedPDU;

·         import org.snmp4j.smi.*;

·         ...

·         ScopedPDU pdu = new ScopedPDU();

·         pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.2.1"))); // ifNumber

·         pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.2.2.1.10"))); // ifInOctets

·         pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.2.2.1.16"))); // ifOutOctets

·         pdu.setType(PDU.GETBULK);

·         pdu.setMaxRepetitions(50);

·         // Get ifNumber only once

·         pdu.setNonRepeaters(1);

·         // set context non-default context (default context does not need to be set)

·         pdu.setContextName(new OctetString("subSystemContextA"));

·         // set non-default context engine ID (to use targets authoritative engine ID

·         // use an empty (size == 0) octet string)

·         pdu.setContextEngineID(OctetString.fromHexString("80:00:13:70:c0:a8:01:0d"));

·         ...

   

  • SNMPv1 TRAP PDU

·          

·         import org.snmp4j.PDUv1;

·         ...

·         PDUv1 pdu = new PDUv1();

·         pdu.setType(PDU.V1TRAP);

·         pdu.setGenericTrap(PDUv1.COLDSTART);

·         ...

   

  • SNMPv2c/SNMPv3 INFORM PDU

·          

·         import org.snmp4j.ScopedPDU;

·         ...

·         ScopedPDU pdu = new ScopedPDU();

·         pdu.setType(PDU.INFORM);

·         // sysUpTime

·         long sysUpTime = (System.currentTimeMillis() - startTime) / 10;

·         pdu.add(new VariableBinding(SnmpConstants.sysUpTime, new TimeTicks(sysUpTime)));

·         pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, SnmpConstants.linkDown));

·         // payload

·         pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.2.2.1.1"+downIndex),

·                                     new Integer32(downIndex)));

·         ...

   

Target 实例

  • Community Target

·          

·         CommunityTarget target = new CommunityTarget();

·         target.setCommunity(new OctetString("public"));

·         target.setAddress(targetAddress);

·         target.setVersion(SnmpConstants.version1);

   

  • User Target

·          

·         UserTarget target = new UserTarget();

·         target.setAddress(targetAddress);

·         target.setRetries(1);

·         // set timeout to 500 milliseconds -> 2*500ms = 1s total timeout

·         target.setTimeout(500);

·         target.setVersion(SnmpConstants.version3);

·         target.setSecurityLevel(SecurityLevel.AUTH_PRIV);

·         target.setSecurityName(new OctetString("MD5DES"));

发送SNMP消息

SNMP4J使用SNMP 会话接口的实例来发送SNMP消息。这个接口的默认实现是Snmp类。

创建一个Snmp类的实例就必须调用它的带有TransportMapping参数的构造函数。transport mappingSNMP会话用来表示对一个远程系统发送SNMP消息时采用的传输协议,例如用户数据报协议(UDP)。

一个SNMP4JSnmp实例支持 SNMP v1v2cv3(默认)版本。对于SNMP协议的其它版本可以通过子类华Snmp来支持。

利用SNMP4J,可以采用同步(阻塞)和异步方式来发送SNMP消息。Snmp类对于同步和异步请求没有采用一个内部线程来处理响应信息,而是采用transport mapping的接收线程来处理响应信息。

通过调用一个实现了ResponseListener接口的类的实例的回调方法来接受异步响应信息。回调方法的执行代表了transport mapping线程接收到了响应包。因此,如果被调用的方法阻塞了,transport mapping的监听端口的同步及异步消息的接收也将被阻塞。其它的transport mapping不会受到影响。通过采用同步消息或在回调方法中解耦来避免阻塞。

发送同步消息的实例

import org.snmp4j.*;

...

Snmp snmp = new Snmp(new DefaultUdpTransportMapping());

snmp.listen();

...

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());

}

发送异步消息的实例

import org.snmp4j.*;

import org.snmp4j.event.*;

...

Snmp snmp = new Snmp(new DefaultUdpTransportMapping());

snmp.listen();

...

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);

        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);

...

接收SNMP消息

SNMP4J通过transport mappings的监听端口来接受SNMP消息。为了能够接收到响应或请求信息,端口必须被设置为监听模式。必须通过调用TransportMapping实例的listen()方法来启动transport mappings的内部监听线程。通过调用TransportMapping实例或者关联的Snmp实例的close()方法来停止这个内部线程并关闭监听端口。

transport mapping以字节流的形式接收到SNMP消息并将消息转发给关联的MessageDispatcher实例。SNMP4J默认采用MessageDispatcherImpl类来解码和分发收到的消息。MessageDispatcher实例在Snmp类内部被创建和使用。

Snmp类处理未完成的请求的响应信息并且转发其它的SNMP消息的PDU给已注册的CommandResponder监听器实例。为了接收SNMP消息必须像下面这样:

  1. 创建一个TransportMapping并且通过调用TransportMapping.listen()初始化它的监听端口。
  2. 利用上边的TransportMapping创建一个Snmp实例。
  3. 实例化一个实现了CommandResponder接口的类,并且通过调用Snmp实例的Snmp.addCommandResponder(CommandResponder)的方法来注册它。

当接收到一个未处理的SNMP消息(一个没有对应的未完成的requestSNMP消息),CommandResponderprocessPdu(CommandResponderEvent)方法将被调用,此方法携带了SNMP消息中的由消息处理模型解码的PDU及附加信息。

接收SNMP消息的实例

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);

snmp.listen();

...

public synchronized void processPdu(CommandResponderEvent e) {

    PDU command = e.getPdu();

    if (command != null) {

    ...

    }

}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值