用snmp4j开发网管应用(二) -- 使用snmp4j

SNMP协议还算简单

其实针对协议的开发我们只要知道协议的内容,然后架起Socket服务器,然后用字符串拼出协议内容格式的字符串,使用Socket进行通信就好了。

针对协议的开源包主要把这些过程封装了。比如SNMP协议。

我们只需要针对PDU对象编程,然后SNMP4j就会把PDU对象转化为SNMP4j协议的格式,进行BER编码,然后传输,最后解码,再翻译为PDU对象。

先看一下SNMP协议要传输的内容:

http://www.cnpaf.net/Class/SNMP/200408/43.html

这个文章中说的很全和好了。接下来就是用SNMP4J协议的jar包来完成各个功能。

http://www.snmp4j.org/html/download.html

在这个网址中下载最新的SNMP4J的jar包,

或者是这个链接下载http://download.csdn.net/detail/three_man/7478029

顺便可以把SNMP4J-Agent-2.2-Instrumentation-Guide.pdf 这个文档描述了对Agent进行开发。

这个文档的下载链接:http://download.csdn.net/detail/three_man/7477953

SNMP4J把开发包分为了两个,一个SNMP4J.jar主要负责get,trap,set,一个是SNMP4J-Agent.jar主要负责作为一个网元被管理。

 

1 首先说一下怎么开发一个Agent.

 需要用到两个配置文件bc和cfg文件,可以在这里下载:http://download.csdn.net/detail/three_man/7477991

大概的代码为:

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.snmp4j.agent.BaseAgent;
import org.snmp4j.agent.CommandProcessor;
import org.snmp4j.agent.DuplicateRegistrationException;
import org.snmp4j.agent.io.ImportModes;
import org.snmp4j.agent.mo.DefaultMOTable;
import org.snmp4j.agent.mo.MOTableRow;
import org.snmp4j.agent.mo.snmp.RowStatus;
import org.snmp4j.agent.mo.snmp.SnmpCommunityMIB;
import org.snmp4j.agent.mo.snmp.SnmpNotificationMIB;
import org.snmp4j.agent.mo.snmp.SnmpTargetMIB;
import org.snmp4j.agent.mo.snmp.StorageType;
import org.snmp4j.agent.mo.snmp.VacmMIB;
import org.snmp4j.agent.security.MutableVACM;
import org.snmp4j.mp.MPv3;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityModel;
import org.snmp4j.security.USM;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.Variable;  

public class MyAgent extends BaseAgent {
    private List<DefaultMOTable> moTables = new ArrayList<DefaultMOTable>();
    private String community;  

    protected MyAgent(File bootCounterFile, File configFile, List<DefaultMOTable> moTables, String community) {
        super(bootCounterFile, configFile, new CommandProcessor(new OctetString(MPv3.createLocalEngineID())));
        this.moTables = moTables;
        this.community = community;
    }  

    @Override
    protected void registerManagedObjects() {
        try {
            for (DefaultMOTable table : moTables) {
                server.register(table, null);
            }
        } catch (DuplicateRegistrationException e) {
            e.printStackTrace();
        }
    }  

    public void startUp(){
        try {
            this.init();
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.loadConfig(ImportModes.REPLACE_CREATE);
        this.addShutdownHook();
        this.getServer().addContext(new OctetString(community));
        this.finishInit();
        this.run();
        this.sendColdStartNotification();
    }  

    /**
     * to set community
     */
    @Override
    protected void addCommunities(SnmpCommunityMIB communityMIB) {
        Variable[] com2sec = new Variable[] {
                new OctetString(community),                     // community name
                new OctetString("cpublic"),                 // security name
                getAgent().getContextEngineID(),            // local engine ID
                new OctetString(community),                     // default context name
                new OctetString(),                          // transport tag
                new Integer32(StorageType.nonVolatile),     // storage type
                new Integer32(RowStatus.active)             // row status
        };
        MOTableRow row =
            communityMIB.getSnmpCommunityEntry().createRow(
                    new OctetString("public2public").toSubIndex(true), com2sec);
        communityMIB.getSnmpCommunityEntry().addRow(row);  

    }
} 
  •  主要的代码是需要继承BaseAgent
  • 需要设置community
  • 需要注册Table,这个注册中的内容将是供给get和walk的内容。
  • 可以从MIB直接构建Agent,可能需要的包为:mibble-mibs是能够独MIB结构。这个也提供个下载地址吧: http://download.csdn.net/detail/three_man/7478061

2. Trap Receiver

   

import java.io.IOException;
import java.util.logging.Logger;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;
import com.prince.snmp.tool.Command;
import com.prince.snmp.tool.util.Configure;
import com.prince.snmp.tool.util.Const;  

/**
 * 构建一个多线程的Trap Receiver
 * @author wangzijian
 *
 */
public class SnmpReceiver implements Command{
    private final Logger log = Logger.getLogger(SnmpReceiver.class.getName());  

    @Override
    public void startUp() throws IOException {
        log.info("Snmp Trap Receiver Start");
        log.info("listened on " + Configure.getInstance().getUdpTrapIpPort());
        ThreadPool pool = ThreadPool.create(Const.THREAD_POOL_NAME, Const.AGENT_THREAD_NUM);
        MultiThreadedMessageDispatcher dispatcher = new MultiThreadedMessageDispatcher(pool, new MessageDispatcherImpl());
        Address listenAddress = GenericAddress.parse(Configure.getInstance().getUdpTrapIpPort());
        TransportMapping transport = new DefaultUdpTransportMapping((UdpAddress) listenAddress);
        // 构建SNMP,并且使其开始监听
        Snmp snmp = new Snmp(dispatcher, transport);
        snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());
        snmp.listen();
        snmp.addCommandResponder(new CommandResponderImpl());
    }
}  

package com.prince.snmp.tool.receiver;  

import java.util.List;
import java.util.logging.Logger;
import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.PDU;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.VariableBinding;  

public class CommandResponderImpl implements CommandResponder {
    private final Logger log = Logger.getLogger(CommandResponderImpl.class.getName());  

    @Override
    public void processPdu(CommandResponderEvent event) {
        PDU pdu = event.getPDU();
        if(PDU.TRAP == pdu.getType()){
            operate(pdu);
        }else{
            log.info("pdu method is:" + pdu.getType() + " not a trap");
        }  

    }  

    private void operate(PDU pdu) {
        List<VariableBinding> bindings = pdu.getBindingList(new OID(".1"));  

        for (VariableBinding binding : bindings) {
            System.out.println(binding.getOid() + "====" + binding.getVariable().toString());
        }
    }
}  
  •  需要一个多线程的服务器MultiThreadedMessageDispatcher
  • 还需要一个处理类 CommandResponderImpl  snmp.addCommandResponder
  • 在处理类中能够得到PDU,这个类不只可以作为Receiver还能够开发为Agent,但是需要自己来写很多逻辑,还有可能用到文件或者内存数据库

3. send trap

package com.prince.snmp.tool.trap;  

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Vector;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import com.prince.snmp.tool.Command;
import com.prince.snmp.tool.trap.dataGenerator.ITrapGenerator;
import com.prince.snmp.tool.util.Configure;  

public class TrapSender implements Command{
    private Snmp snmp;
    private Address targetAddress;
    private ITrapGenerator generator;  

    public TrapSender(ITrapGenerator generator) {
        this.generator = generator;
        targetAddress = GenericAddress.parse(Configure.getInstance().getUdpTrapIpPort());
        TransportMapping<UdpAddress> transport = null;
        try {
            transport = new DefaultUdpTransportMapping();
            snmp = new Snmp(transport);
            transport.listen();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }  

    public void sendTrap(){
        CommunityTarget target = new CommunityTarget();
        target.setAddress(targetAddress);
        target.setRetries(Configure.getInstance().getRetries());
        target.setTimeout(Configure.getInstance().getTimeOut());
        target.setCommunity(new OctetString(Configure.getInstance().getCommunity()));
        target.setVersion(Configure.getInstance().getSnmpVersion());  

        List<TrapData> datas = generator.generateTrapData();  

        try {
            for (TrapData trapData : datas) {
                sendPdu(trapData, target);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }  

    private void sendPdu(TrapData trapData, CommunityTarget target) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, IOException {
        PDU pdu = MoToPdu.moToPdu(trapData);
        ResponseEvent respEvnt = snmp.send(pdu, target);  

        // 解析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());
            }
        }
    }  

}  
  •   trap主要注意必须设置两个VariableBingding

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

 

                pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID(trap.getTrapOid())))

4. get

private static void simpleGet() throws IOException {
    TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
    Snmp snmp = new Snmp(transport);
    transport.listen();  

    CommunityTarget target = new CommunityTarget();
    target.setCommunity(new OctetString("CONV"));
    Address targetAddress = GenericAddress.parse("udp:10.141.43.237/161");
    target.setAddress(targetAddress);
    target.setRetries(3);
    target.setTimeout(3000);
    target.setVersion(SnmpConstants.version2c);  

    PDU pdu = new PDU();
       pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.7569.1.2.1.23.3.1")));
       pdu.setType(PDU.GETBULK);
       pdu.setMaxRepetitions(20);
       pdu.setNonRepeaters(0);  

       ResponseEvent respEvnt = snmp.send(pdu, target);
       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());    

              }    

       }
}  
  •      get相对于比较简单,资料也比较多。主要是设定pdu.setType(PDU.GETBULK);
  • 利用getnext和一些判断可以实现walk.
  • http://blog .sina.com.cn/s/blog_6cb15f8f0100yx4p.html 这个哥们儿写得非常好

具体的代码没有写,因为下一篇会共享一个小的工具,可以以配置文件为基础来构建Receiver,发送Trap,构建Agent等。

时间: 2024-09-16 20:15:57

用snmp4j开发网管应用(二) -- 使用snmp4j的相关文章

用snmp4j开发网管应用(一) - SNMP

要开发网管应用,SNMP是必学的协议,这里首先对SNMP进行一下简单的介绍和想要开发SNMP协议的内容所需要用到的工具.   SNMP SNMP 协议分为了多个版本,V1太简单,V2加入了一些验证,V3最严谨,下面都是以V2进行说明 概念: ASN.1 高级数据描述语言,用于定义数据类型,语法规则等. BER ASN.1的基本编码规则,发送消息之前经过其编码,接收后先解码 SMI 管理信息结构,ASN.1的子集加上一部分宏等内容.SNMP用它来描述MIB和PDU MIB 管理信息库,一般是一个树

WEB开发网推出CMS第三方演示平台

中介交易 SEO诊断淘宝客 站长团购 云主机 技术大厅 3月12日讯 专注CMS领域的站长门户WEB开发网( www.cncms.com.cn)今日正式推出CMS演示平台,该平台的上线为WEB程序员提供了广阔的作品展示空间,让广大站长通过实际的使用对比,快速的找到适合自己的CMS建站程序.据了解,这将是国内首个集中展示CMS产品及二次开发应用的第三方演示平台. 据WEB开发网CMS频道负责人陈清泉介绍,演示平台的上线,在相同的环境.相同功能的情况下,使用者可以更直观的对不同CMS产品进行对比和测

智冠王俊博:最初投2千万开发网游两年都睡不着

7月23日下午消息,台湾网游厂商智冠科技总经理王俊博在ChinaJoy网游十年高峰 对话上表示,最初决定投资2000万开发网游,结果两年晚上都睡不着觉. 王俊博回忆称,十年前其实已经在开发游戏了.1999年的时候,有四个技术人员想开发网络游戏找到了自己,当时台湾只有一款网络游戏叫做<网络创世纪>.与他们沟通后,发现研发这样一款网游需要2000万台币,"那时候2000万是很多的.后来我说我回去考虑一下."王俊博表示. "一个礼拜后,决定要做了."王俊博表示

关于WPF+WCF开发网游

问题描述 一款2D的网游,客户端我想用WPF来开发,服务器端用WCF来做,想请教一下大家,这种想法可行度是多少?细心听取一下大家的意见中.... 解决方案 解决方案二:WPF处理图像性能慢,微软官方建议开发游戏最好还是用DirectX.解决方案三:UP解决方案四:UP解决方案五: 解决方案六:Mark解决方案七:慢慢学习PS:我的目标是---->^_^解决方案八:WPF是用来做界面的做游戏还是需要使用DX服务器那边就不懂了觉得服务器那端应该采用较稳定的技术为好.解决方案九:.解决方案十:支持楼主

巴勒斯坦青年开发网游,模拟赶出以色列

据卡塔尔半岛电视台网站11月3日报道,巴勒斯坦青年开发了一款名为<解放巴勒斯坦>的策略类网游,该网游模拟了将以色列从巴勒斯坦被占领土上驱逐出去的战役. 该网游的开发者阿卜杜拉·艾哈迈德在半岛电视台的采访中表示,游戏<解放巴勒斯坦>是首款由巴勒斯坦人设计.模拟"将巴勒斯坦从以色列的攻击中解放出来"的二维游戏.玩家可以选择边境地区作为战场,开始游戏中解放巴勒斯坦的进程. 艾哈迈德认为,该游戏适合各年龄阶段的人,但其主要的目标人群是经常接触网络的青少年.通常而言,这一

请程序员开发网(http://www.pudn.com/)的会员朋友帮忙下份资料

问题描述 跪求大侠们帮帮忙,很急!!!下面是两份资料的链接(TheDesignOfGameOnP2P,jxtagame)http://www.pudn.com/downloads90/doc/detail343616.htmlhttp://www.pudn.com/downloads76/sourcecode/java/detail283459.html邮箱:zjgoodluck@yahoo.cnQQ:309191851

JAVA游戏龙头开发网游《恒星黎明》明年发行

7月15日消息,英国游戏开发商.JAVA游戏界龙头老大Jagex公布了新的网游项目,该公司最出名的作品是流行网游<江湖Runescape>.新作的题材是科幻类型,暂命名为<恒星黎明(Stellar Dawn)>. 这款游戏预计于明年发行,Jagex称游戏的特色是"科幻小说的故事情节和多样化的游戏风格",并且会"随着玩家在游戏中的进步,提供给玩家探讨未来的广阔世界.接触广泛背景故事的机会." "<恒星黎明(Stellar Daw

《光环》开发商证实开发网游否认太空版魔兽

(编译/ANANAS)据海外媒体报道,在昨日的全球游戏开发者大会中,Bungie公司宣布其下一个研发项目将是一款大型多人动作游戏. Bungie公司首席网络工程师David Aldridge出面否认了之前对新游戏的一些相关描述,并且明确指出新游戏不会是一款类似<魔兽世界>的大型网游. 早在上个月,有消息称,Bungie公司的下一个游戏研发项目将会是命名为<Destiny>的大型多人在线第一人称射击游戏.而在此次在开发者大会中,Bungie给出的声明中只是说会是一款动作游戏,所以并不

英国交通部高价开发网游上市一年后无人问津

(编译/Wendy)据国外媒体报道,由英国交通部在2009年发起的免费道路安全网游项目最近被披露只有寥寥数千注册用户,而已经花费了英国纳税人280万英镑. 这个免费网游名为<艾沃安之典(Code of Everand)>,在2009年11月上市的,光是维护费用就花费了70万英镑.自从游戏启动后的前几个月形势很乐观,游戏吸引了5.4万用户,在2010年3月达到最高值,但是随后用户兴趣急剧下降,直到2010年底新注册用户数量都不见增多. 游戏自称目前有17万用户,而这只是注册用户并非活跃用户,从F