关于通过snmp4j Java库在多线程环境中的snmp v3请求

问题描述

我正在通过snmp4j Java库将SNMP v3请求发送到第一台snmpv3服务器,并且工作正常。通过snmp4j库将SNMP v3请求发送到第二个snmpv3服务器也可以正常工作。但是,如果我从如下所示的同一程序中的两个不同线程向两个服务器发送消息,则其中一个给出的响应为空 如下:-

203> responsePDU ==空:

错误:空 地址:空 来源:com.x.x.x.SnmpV2@755ca288)。

我敢打赌,由于SecurityModels是Singleton类,因此以下两行可能会造成混乱。

USM usm = new USM(SecurityProtocols.getInstance(),new OctetString(MPv3.createLocalEngineID()),0);
    SecurityModels.getInstance().addSecurityModel(usm);

下面是代码:-

在多线程环境中使用v3的snmp4j的任何经验...

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.AuthSHA;
import org.snmp4j.security.PrivAES128;
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.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;

public class MultiThreadedSnmpV3Request {
    public static void main(String[] args) throws Exception {
        MultiThreadedSnmpV3Request requests = new MultiThreadedSnmpV3Request();
        new Thread(() -> {
            try {
                requests.firstServerRequest();
            } catch (Exception e) {
                e.printstacktrace();
            }
        }).start();

        new Thread(() -> {
            try {
                requests.secondServerRequest();
            } catch (Exception e) {
                e.printstacktrace();
            }
        }).start();
    }

    private void firstServerRequest() throws Exception {
        String targetAddress = "udp:10.99.220.203/161";
        String userName = "xxxx";
        OID authProtocol = AuthSHA.ID;
        String authPassphrase = "f8T7wWXeJ6brNeNF";
        OID privProtocol = PrivAES128.ID; // PrivAES256.ID;
        String privPassphrase = "KpbnkSJrP5Kgbhqb";

        // build a PDU with all the OIDs
        UserTarget target = new UserTarget();
        target.setTimeout(5000);
        target.setVersion(SnmpConstants.version3);
        target.setAddress(GenericAddress.parse(targetAddress));
        target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
        target.setSecurityName(new OctetString(userName));

        TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
        SnmpV2 snmp = new SnmpV2(transport);
        USM usm = new USM(SecurityProtocols.getInstance(),0);
        SecurityModels.getInstance().addSecurityModel(usm);
        // add user to the USM
        snmp.getUSM().addUser(new OctetString(userName),new UsmUser(new OctetString(userName),authProtocol,new OctetString(authPassphrase),privProtocol,new OctetString(privPassphrase)));

        transport.listen();
        ScopedPDU requestPDU = new ScopedPDU();
        requestPDU.add(new VariableBinding(new OID("1.3.6.1.4.1.2021.2.1.2.1")));
        requestPDU.setType(PDU.GET);

        for (int i = 0; i < 20; i++) {
            Thread.sleep(3000);
            ResponseEvent re = snmp.send(requestPDU,target);
            PDU responsePDU = re.getResponse();
            if (responsePDU == null) {
                System.out.println("1st Server > responsePDU == null :");
                System.out.println("> Error     : " + re.getError());
                System.out.println("> Address     : " + re.getPeerAddress());
                System.out.println("> Source      : " + re.getSource());
                System.out.println("> User object : " + re.getUserObject());
            } else if (responsePDU.getvariableBindings() != null) {
                for (VariableBinding vb : responsePDU.getvariableBindings()) {
                    System.out.println("1st Server >> " + vb.getoid() + " --> " + vb.getvariable());
                }
            }
        }
    }

    private void secondServerRequest() throws Exception {
        String targetAddress = "udp:10.99.220.204/161";
        String userName = "xxxx";
        OID authProtocol = AuthSHA.ID;
        String authPassphrase = "f8T7wWXeJ6brNeNF";
        OID privProtocol = PrivAES128.ID; // PrivAES256.ID;
        String privPassphrase = "KpbnkSJrP5Kgbhqb";

        UserTarget target = new UserTarget();
        target.setTimeout(5000);
        target.setVersion(SnmpConstants.version3);
        target.setAddress(GenericAddress.parse(targetAddress));
        target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
        target.setSecurityName(new OctetString(userName));

        TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
        Snmp snmp = new Snmp(transport);
        USM usm = new USM(SecurityProtocols.getInstance(),new OctetString(privPassphrase)));

        transport.listen();

        ScopedPDU requestPDU = new ScopedPDU();
        requestPDU.add(new VariableBinding(new OID("1.3.6.1.4.1.2021.2.1.2.1")));
        requestPDU.setType(PDU.GET);
        for (int i = 0; i < 20; i++) {
            Thread.sleep(3000);
            ResponseEvent re = snmp.send(requestPDU,target);
            PDU responsePDU = re.getResponse();
            if (responsePDU == null) {
                System.out.println("2nd Server> responsePDU == null :");
                System.out.println("> Error     : " + re.getError());
                System.out.println("> Address     : " + re.getPeerAddress());
                System.out.println("> Source      : " + re.getSource());
                System.out.println("> User object : " + re.getUserObject());
            } else if (responsePDU.getvariableBindings() != null) {
                for (VariableBinding vb : responsePDU.getvariableBindings()) {
                    System.out.println("2nd Server >> " + vb.getoid() + " --> " + vb.getvariable());
                }
            }
        }

    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)