对SNMP4J的一些封装

SNMP4J是一个开源的,用Java实现的snmp协议。其中提供了一下API,在这些API上面封装了一些方法,比如SNMP的get-request请求,get-next-request请求等

如果不了解SNMP协议的点我(不是我写的)

下面贴我封装的Java代码(后面还会封装一些其他请求,比如说请求一个表格等操作)

SNMP4J jar包或源码下载点我(不用翻墙) www.snmp4j.org

定义接口Snmp_aip_interface.java

import java.util.List;

public interface Snmp_aip_interface {
    /**
     * 根据ip,oid返回get消息
     * @param ip
     * @param oid
     * @return
     */
    public String get(String ip, String oid_str);
    
    /**
     * 根据ip,oid和新值设置oid节点的值
     * @param ip
     * @param oid_str
     * @param value_new
     */
    public void set(String ip, String oid_str, String value_new);
    
    /**
     * 根据ip,oid返回getNext消息
     * @param ip
     * @param oid_str
     * @return
     */
    public String getNext(String ip, String oid_str);
    
    /**
     * 根据ip,oid获取bulk消息
     * @param ip
     * @param oid_str
     * @return
     */
    public List<String> getBulk(String ip, String oid_str);
    
    /**
     * snmp v3版get api
     * @param ip
     * @param oid_str
     * @return
     */
    public String getV3(String ip, String oid_str);
    
    /**
     * 向ip地址发送消息,这里利用发送trap消息来发送任意消息
     * @param ip
     * @param message
     */
    public void sendMessage(String ip, String message);
}

对接口的实现Snmp_api.java

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.UserTarget;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.PrivDES;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.Variable;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;

import com.gxf.snmpinterceptor.Snmp_aip_interface;


/**
 * 封装snmp v 2的消息格式,对外提供接口
 * 使用开源snmp4j进行封装
 * 代理端监听udp 161端口,管理端监听的是udp 162端口
 * snmp2c提供的消息格式,Get,GetNext,Set,Reponse,Trap,GetBulk,
 * @author Administrator
 * 
 * PDU类型 版本(0)|共同体|PDU类型(0-3)|请求标识|差错索引|差错状态(0-5)|差错索引|名称|值|名称|值...
 * 
 * trap
 * 
 *                     |PDU类型(0-3)|企业|代理地址|trap类型(0-6)|特定代码|时间戳|名称|值..
 *
 */
public class Snmp_api implements Snmp_aip_interface{
    private Snmp snmp;
    private TransportMapping transportMapping;
    private int timeOut;
    private int timesRetry;
    
    public Snmp_api(){
//        Thread thread_rec = new receiveTrapThread();
//        thread_rec.start();
//        listen();
    }
    
    private void init(){
        try {
            transportMapping = new DefaultUdpTransportMapping();
        } catch (IOException e) {
            System.out.println("init transportMapping failed!");
            System.out.println(e.getMessage());
        }
        snmp = new Snmp(transportMapping);
        timeOut = 1500;
        timesRetry = 2;
    }
    
    /**
     * 根据ip,oid返回get消息
     * @param ip
     * @param oid
     * @return
     */
    public String get(String ip, String oid_str){
        init();
        String ret = "";    
        //构造PDU
        PDU pdu = new PDU();
        OID oid = new OID(oid_str);
        VariableBinding vb = new VariableBinding(oid);
        pdu.add(vb);
        pdu.setType(PDU.GET);
        
        //构造target
        String address_str = "udp:" + ip + "/161";
//        String address_str = "udp:210.38.235.184/161";
        Address address = GenericAddress.parse(address_str);
        OctetString name_com = new OctetString("public");
        CommunityTarget target = new CommunityTarget();
        target.setAddress(address);                                        //设置address
        target.setRetries(timesRetry);
        target.setTimeout(timeOut);
        target.setVersion(SnmpConstants.version2c);                        //设置版本号
        target.setCommunity(name_com);                                    //设置团体名
        
        try {
            this.transportMapping.listen();
        } catch (IOException e) {
            System.out.println("transportMapping.listen() failed!");
            System.out.println(e.getMessage());
        }
        ResponseEvent responseEvent = null;
        //发送消息
        try {
            responseEvent = snmp.send(pdu, target);
        } catch (IOException e) {
            System.out.println("snmp.send(pdu, target) failed");
            System.out.println(e.getMessage());
        }
        //获取结果
        if(responseEvent != null){
            PDU pdu_rep = responseEvent.getResponse();
            for(int i = 0; i < pdu_rep.size(); i++){
                VariableBinding vb_temp = pdu_rep.get(i);
                Variable var_temp = vb_temp.getVariable();
                ret += var_temp.toString();
            }//for
        }//if
        try {
            transportMapping.close();                                    //关闭正在进行的监听                
        } catch (IOException e) {
            System.out.println("transportMapping.close() failed!");
            System.out.println(e.getMessage());
        }
        return ret;
    }
    
    
    /**
     * 根据ip,oid和新值设置oid节点的值
     * @param ip
     * @param oid_str
     * @param value_new
     */
    public void set(String ip, String oid_str, String value_new){
        init();
        //构造PDU
        PDU pdu = new PDU();
        OID oid = new OID(oid_str);
        VariableBinding vb = null;
        
        vb = new VariableBinding(oid, new OctetString(value_new));
        
        pdu.add(vb);
        pdu.setType(PDU.SET);
        
        //构造target
        String address_str = "udp:" + ip + "/161";
        CommunityTarget target = new CommunityTarget();
        OctetString com_oct = new OctetString("public");
        target.setCommunity(com_oct);                                    //设置团体名
        Address address = GenericAddress.parse(address_str);
        target.setAddress(address);                                        //设置address
        target.setVersion(SnmpConstants.version2c);                     //设置版本号
        target.setTimeout(1500);
        target.setRetries(timesRetry);
        
        //发送pdu
        try {
            transportMapping.listen();
        } catch (IOException e) {
            System.out.println("listen failed in set pdu");
            System.out.println(e.getMessage());
        }
        try {
            snmp.send(pdu, target);
        } catch (IOException e) {
            System.out.println("send failed in send set message!");
            System.out.println(e.getMessage());
        } finally{
            try {
                transportMapping.close();                                //关闭正在进行的监听
            } catch (IOException e) {
                System.out.println("transportMapping.close() failed!");
                System.out.println(e.getMessage());
            }
        }
    }

    /**
     * 根据ip,oid返回getNext消息
     * @param ip
     * @param oid_str
     * @return
     */
    public String getNext(String ip, String oid_str){
        init();
        String ret = "";
        //构造PDU
        PDU pdu = new PDU();
        OID oid = new OID(oid_str);
        VariableBinding vb = new VariableBinding(oid);
        pdu.add(vb);
        pdu.setType(PDU.GETNEXT);
        
        //构造target
        String address_str = "udp:" + ip + "/161";                                    //UDP和ip
        CommunityTarget target = new CommunityTarget();
        Address address = GenericAddress.parse(address_str);
        target.setCommunity(new OctetString("public"));
        target.setAddress(address);
        target.setTimeout(timeOut);
        target.setRetries(timesRetry);
        target.setVersion(SnmpConstants.version2c);                                 //设置版本号
        
        ResponseEvent responseEvent = null;
        
        try {
            this.transportMapping.listen();                                            //开始监听
        } catch (IOException e1) {
            System.out.println("transportMapping.listen() failed!");
            System.out.println(e1.getMessage());
        }
        
        //发送消息
        try {
            responseEvent = snmp.send(pdu, target);                
            if(responseEvent != null){                                                //组装返回的消息
                PDU pdu_reponse = responseEvent.getResponse();
                for(int i = 0; pdu_reponse != null && i < pdu_reponse.size(); i++){
                    VariableBinding vb_temp = pdu_reponse.get(i);
                    Variable var_temp = vb_temp.getVariable();
                    ret += var_temp.toString();
                }
            }
        } catch (IOException e) {
            System.out.println("snmp.send(pdu, target) failed! in getNext");
            e.printStackTrace();
        } finally{                                                                    //关闭监听
            try {
                this.transportMapping.close();
                snmp.close();
            } catch (IOException e) {
                System.out.println("transportMapping.close() failed!");
                System.out.println(e.getMessage());
            }
        }//finally
        
        return ret;
    }

    /**
     * 根据ip,oid获取bulk消息
     * @param ip
     * @param oid_str
     * @return
     */
    public List<String> getBulk(String ip, String oid_str){
        init();
        List<String> ret = new ArrayList<String>();
        //构造PDU 
        PDU pdu = new PDU();
        pdu.setType(PDU.GETBULK);
        pdu.setMaxRepetitions(200);
        pdu.setNonRepeaters(0);
        OID oid = new OID(oid_str);
        VariableBinding vb = new VariableBinding(oid);
        pdu.add(vb);
        
        //构造target
        String address_str = "udp:" + ip + "/161";                                    //UDP和ip
        CommunityTarget target = new CommunityTarget();
        Address address = GenericAddress.parse(address_str);
        target.setCommunity(new OctetString("public"));
        target.setVersion(SnmpConstants.version2c);
        target.setAddress(address);
        target.setTimeout(timeOut);
        target.setRetries(timesRetry);
        
        try {                                                                        //开始监听UDP端口
            this.transportMapping.listen();
        } catch (IOException e) {
            System.out.println("transportMapping.listen() failed!");
            System.out.println(e.getMessage());
        }
        
        //发送消息
        ResponseEvent responseEvent = null;
        try {
            responseEvent = this.snmp.send(pdu, target);
        } catch (IOException e) {
            System.out.println(".snmp.send(pdu, target) failed! in getBulk");
            e.printStackTrace();
        }
        
        if(responseEvent != null){
            PDU pdu_rec = responseEvent.getResponse();
            
            System.out.println(pdu_rec.size());                                            //输出为0,说明前面没有获取到数据
            for(int i = 0; i < pdu_rec.size(); i++){
                String str_temp = "";
                VariableBinding vb_temp = pdu_rec.get(i);
                str_temp += vb_temp.getOid() + " ";
                str_temp += vb_temp.getVariable().toString();
                ret.add(str_temp);
            }//for
        }//if
        
        try {
            this.transportMapping.close();
        } catch (IOException e) {
            System.out.println("transportMapping.close() failed!");
            System.out.println(e.getMessage());
        }
        
        return ret;
    }
    
    /**
     * 接收trap消息线程
     * @author Administrator
     *
     */
    private class receiveTrapThread extends Thread{
        public void run(){
            System.out.println("start run thread..");
            
            try {
                transportMapping.listen();
            } catch (IOException e) {
                System.out.println("listen failed in receiveTrapThread.run()!");
                e.printStackTrace();
            }
            CommandResponder commandResponder = new CommandResponder(){
                @Override
                public void processPdu(CommandResponderEvent event) {
                    System.out.println("enter processPdu()...");
                    PDU pdu_receive = event.getPDU();
                    StringBuffer sb = new StringBuffer();
                    
                    for(int i = 0; i < pdu_receive.size(); i++){
                        VariableBinding vb_temp = pdu_receive.get(i);
                        sb.append(vb_temp.getVariable().toString());
                    }//for
                    System.out.println(sb.toString());
                }
                
            };
            snmp.addCommandResponder(commandResponder);
        }
    }
    
    public synchronized void listen(){
        System.out.println("start listen..");
        try {
            this.wait();
        } catch (InterruptedException e) {
            
            e.printStackTrace();
        }
    }

    
    /* (non-Javadoc)
     * @see com.gxf.snmp.interfaces.Snmp_aip_interface#getV3(java.lang.String, java.lang.String)
     */
    @Override
    public String getV3(String ip, String oid_str) {
        Snmp snmp = null;
        try {
            snmp = new Snmp(new DefaultUdpTransportMapping());
        
        USM usm = new USM(SecurityProtocols.getInstance(),
                          new OctetString(MPv3.createLocalEngineID()), 0);
        SecurityModels.getInstance().addSecurityModel(usm);
        
        snmp.listen();
        } catch (IOException e) {
            e.printStackTrace();
        }
        UsmUser user = new UsmUser(
                    new OctetString("luckygxf"),
                    AuthMD5.ID, new OctetString("luckygxf"),
                    PrivDES.ID, new OctetString("luckygxf")
                );
        OctetString contextEngineId = new OctetString("0002651100[02]");
        snmp.getUSM().addUser(new OctetString("nmsAdmin"), new OctetString("0002651100"), user);
        snmp.getUSM().addUser(new OctetString("luckygxf"), user);
        String address_str = ip + "/161";    
//        System.out.println("address_str = " + address_str);
        Address address = new UdpAddress(address_str);
        UserTarget target = new UserTarget();
        target.setVersion(SnmpConstants.version3);
        target.setAddress(address);
        target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
        target.setSecurityName(new OctetString("luckygxf"));
        target.setTimeout(2000);
        target.setRetries(1);
        
        ScopedPDU pdu = new ScopedPDU();
        pdu.setType(PDU.GET);
        pdu.setContextEngineID(contextEngineId);
        VariableBinding vb = new VariableBinding(new OID(oid_str));
        pdu.add(vb);
        
        ResponseEvent responseEvent = null;
        try {
            responseEvent = snmp.send(pdu, target);
        } catch (IOException e) {
            
            e.printStackTrace();
        }
        StringBuffer sb = new StringBuffer();                        //返回的字符串
        if(null != responseEvent){
            PDU pdu_rec = responseEvent.getResponse();
//            System.out.println("pdu_rec.size() = " + pdu_rec.size());
            if(pdu_rec != null){
                Vector<? extends VariableBinding> vbs = pdu_rec.getVariableBindings();
                for(VariableBinding vb_temp : vbs){
                    sb.append(vb_temp.getVariable().toString());
                }//for
            }
        }//if
        
        try {
            snmp.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
        
    }

    /* (non-Javadoc)
     * @see com.gxf.snmp.interfaces.Snmp_aip_interface#sendMessage(java.lang.String, java.lang.String)
     */
    @Override
    public void sendMessage(String ip, String message) {
        //构造trap PDU
        PDU pdu = new PDU();
        VariableBinding vb = new VariableBinding(new OID("1.3.6.1.2.3377.10.1.1.1.1"), new OctetString(message));        
        pdu.add(vb);
        pdu.setType(PDU.TRAP);
        
        //构造target
        String address_str = "udp:" + ip + "/16200";                            //这里发送端口为16200
        CommunityTarget target = new CommunityTarget();
        Address address = GenericAddress.parse(address_str);
        target.setAddress(address);
        target.setVersion(SnmpConstants.version2c);
        target.setCommunity(new OctetString("public"));
        target.setTimeout(2000);
        target.setRetries(2);
        TransportMapping<UdpAddress> tranportMapping = null;
        try {
            tranportMapping = new DefaultUdpTransportMapping();
            tranportMapping.listen();
        } catch (IOException e) {
            System.out.println("sendTrap(String ip) failed in Snmp_api.sendTrap(String ip)!");
            e.printStackTrace();
        }
        Snmp snmp = new Snmp(tranportMapping);
        try {
            ResponseEvent responseEvent = snmp.send(pdu, target);                //得到回复的pdu
            if(null != responseEvent){
                StringBuffer sb = new StringBuffer();
                PDU pdu_rec = responseEvent.getResponse();
                for(int i = 0;pdu_rec != null && i < pdu_rec.size(); i++){
                    VariableBinding vb_temp = pdu_rec.get(i);
                    sb.append(vb.getVariable().toInt());
                }//for
                
                System.out.println(sb.toString());
            }
        } catch (IOException e) {
            System.out.println("snmp.send(pdu, target) failed in Snmp_api.sendTrap(String ip)!");
        }
        
        try {
            tranportMapping.close();
            snmp.close();                                                                        //关闭tansportmapping and snmp 释放资源
        } catch (IOException e) {
            System.out.println("tranportMapping.close() and snmp.close() failed in Snmp_api.sendTrap(String ip)!");
            e.printStackTrace();
        }
        
    }
}

 P.S.从google code中copy了一份到github中:https://github.com/luckygxf/flower

这个封装的功能更强大

原文地址:https://www.cnblogs.com/luckygxf/p/4918506.html