使用java编写snmp inform 发送与接收示例

环境:java+gradle+snmp4j

编译器idea

进入正题

首先,我们编写一个snmp接收类

package main.snmp.util;

import org.snmp4j.*;
import org.snmp4j.mp.StateReference;
import org.snmp4j.mp.StatusInformation;
import org.snmp4j.smi.TcpAddress;
import org.snmp4j.transport.DefaultTcpTransportMapping;

/**
 * snmp trap和inform接收类
 */
public class InformReceiver implements CommandResponder {
    private int port;
    private Snmp snmp;

    public InformReceiver(int port){
        this.port = port;
    }

    /**
     * 完成初始化并启动监听
     */
    public void startListener() {
        try {
            TransportMapping transport = new DefaultTcpTransportMapping(
                    new TcpAddress(port));
            snmp = new Snmp(transport);
            snmp.addCommandResponder(this);
            snmp.listen();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    
    /**
     * 处理接收到的消息
     */
    @Override
    public void processPdu(CommandResponderEvent event) {
        System.out.print("receive Message :");
        PDU pdu = event.getPDU();
        System.out.println(pdu);

        if(pdu.getType()==PDU.INFORM) {
            //如果是Inform消息,需要回应,如果不回应,那么客户端就会重复inform消息
            pdu.setErrorIndex(0);
            pdu.setErrorStatus(0);
            pdu.setType(PDU.RESPONSE);

            StatusInformation statusInformation = new StatusInformation();
            StateReference ref = event.getStateReference();
            try {
                event.getMessageDispatcher().returnResponsePdu(
                        event.getMessageProcessingModel(),
                        event.getSecurityModel(), event.getSecurityName(),
                        event.getSecurityLevel(), pdu,
                        event.getMaxSizeResponsePDU(), ref, statusInformation);
            } catch (MessageException ex) {
                ex.printStackTrace();
            }
        }
    }
}

接着,我们再编写一个snmp发送类

package main.snmp.util;

import org.snmp4j.*;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.*;
import org.snmp4j.transport.DefaultTcpTransportMapping;

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

/**
 * snmp发送类,发送trap和inform
 */
public class InformSender {

    private Snmp snmp;

    public void Connect() throws IOException {
        TransportMapping<?> mapping = new DefaultTcpTransportMapping();
        snmp = new Snmp(mapping);
    }

    /**
     * 获取时间参数
     * @param currentTime
     * @return
     */
    private static  Variable getSysUpTimeVariable(long currentTime){
        TimeTicks result = new TimeTicks(0);
        long i = 0L;
        if(i == 0L || currentTime == 0L){
        }else{
            result.setValue((currentTime - i)/10);
        }
        return result;
    }

    /**
     * 获取目标地址
     * @param address
     * @param community
     * @return
     */
    public static Target getTargetV2(final String address, final String community){
        Address targetAddress = GenericAddress.parse(address);
        String str = community==null?"":community;
        Target target = new CommunityTarget(targetAddress, new OctetString(str));
        target.setAddress(targetAddress);
        target.setRetries(3);       //当发送trap的时候不生效,发送Inform的时候会生效
        target.setTimeout(1 * 1000);//等待回应时间
        target.setVersion(SnmpConstants.version2c);
        return target;
    }

    /**
     * 构造一个参数列表,用来测试发送数据
     */
    private List<VariableBinding> getVariable(){
        List<VariableBinding> variables = new ArrayList<>();
        VariableBinding upTimeVB = new VariableBinding();
        upTimeVB.setOid(SnmpConstants.sysUpTime);
        Variable upTimeVar = getSysUpTimeVariable(System.currentTimeMillis());
        upTimeVB.setVariable(upTimeVar);
        variables.add(upTimeVB);
        return variables;
    }

    public boolean sendInform(Target target) throws IOException {
        List<VariableBinding> variables = getVariable();
        return sendInform(target, variables);
    }

    /**
     * 发送inform消息
     * @param target
     * @param variables
     * @return
     * @throws IOException
     */
    private boolean sendInform(Target target, List<VariableBinding> variables) throws IOException {
        PDU pdu = new PDU();
        for(VariableBinding vb : variables) {
            pdu.add(vb);
        }

        ResponseEvent response = snmp.inform(pdu, target);
        if(response==null)
            return true;
        if(response.getResponse()==null)
            return false;
        if(response.getError()!=null)
            return false;
        return true;
    }

    public boolean sendTrap(Target target) throws IOException {
        List<VariableBinding> variables = getVariable();
        return sendTrap(target, variables);
    }

    /**
     * 发送trap消息
     * @param target
     * @param variables
     * @return
     * @throws IOException
     */
    private boolean sendTrap(Target target, List<VariableBinding> variables) throws IOException {
        PDU pdu = new PDU();
        pdu.setType(PDU.TRAP);
        for(VariableBinding vb : variables) {
            pdu.add(vb);
        }

        snmp.send(pdu, target);
        return true;
    }
}

最后,我们再编写一个测试类

package main;

import main.snmp.util.InformReceiver;
import main.snmp.util.InformSender;
import org.snmp4j.Target;
import org.snmp4j.TransportMapping;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.OctetString;

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

public class Main {
    public static void main(String[] args){

        //在本机10062端口启动监听
        InformReceiver receiver = new InformReceiver(10062);
        receiver.startListener();
        System.out.println("snmp start listener");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) { }


        InformSender sender = new InformSender();
        try {
            sender.Connect();
            Target target = InformSender.getTargetV2("tcp:127.0.0.1/10062","");

            //发送inform
            boolean result = sender.sendInform(target);
            if(result==true)
                System.out.println("snmp send inform succ.");
            else
                System.out.println("snmp send inform fail.");

            //发送trap,trap只管发送不管结果
            result = sender.sendTrap(target);
            if(result)
                System.out.println("snmp send trap succ.");
            else
                System.out.println("snmp send trap fail.");

        } catch (IOException e) {
            e.printStackTrace();
        }


        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) { }
    }
}

程序的运行结果

如果需要工程,可以去github下载,下载链接是https://github.com/skyfinging/snmp-Inform-demo

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值