关于通过snmp4j java库在多线程环境中进行snmp v3请求

问题描述 投票:0回答:2

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

203> 响应 PDU == null :

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

我敢打赌,由于 SecurityModels 是一个单例类,因此下面两行可能会造成混乱。

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(), new OctetString(MPv3.createLocalEngineID()), 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(MPv3.createLocalEngineID()), 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("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());
                }
            }
        }

    }
}
java snmp snmp4j
2个回答
0
投票
    TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
    Snmp snmp = new Snmp(transport);
    USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 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)));

这些代码应该修改:

TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(new MessageDispatcherImpl(), transport);
SecurityProtocols.getInstance().addDefaultProtocols();
USM usm = new USM(SecurityProtocols.getInstance(), new 
OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
usm.addUser(new OctetString(userName), new UsmUser(new OctetString(userName),authProtocol,new OctetString(authPassphrase), privProtocol,new OctetString(privPassphrase)));
MPv3 mPv3 = new MPv3(usm);
snmp.getMessageDispatcher().addMessageProcessingModel(mPv3);

0
投票

感谢您的回答@li.py,但是对于以前版本的 SNMP4J,MPv3(USM usm) 构造函数不存在,是否有替代方案?

© www.soinside.com 2019 - 2024. All rights reserved.