我使用版本3 USM模型通过SNMP4J发送SNMP请求。但是,当我发送SNMP请求一致的IP1,IP2时,没有问题,一切正常,我收到了两个响应PDU。另外,当我尝试发送IP1,IP3时,一切正常,我成功接收到响应,但是当我同时尝试IP2,IP3时,总是IP3请求失败,并且我收到响应PDU为空。
谁能告诉我这是什么问题?

并发IP1,IP2没问题,一切正常。
并发IP1,IP3没问题,一切正常。
并发IP2,IP3有问题。 IP3响应PDU始终为空。

public class SnmpFetcher {

    static byte[] localEngineID = MPv3.createLocalEngineID();

    static{

        USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(localEngineID), 0);

        SecurityModels.getInstance().addSecurityModel(usm);
    }

    private Logger logger = Logger.getLogger(SnmpFetcher.class);

    private Target target = null;
    private SnmpAgentConfig snmpAgentConfig = null;
    private TransportMapping<? extends Address> transport = null;
    private Snmp snmp = null;

    long startTime = System.currentTimeMillis();

    public SnmpFetcher(SnmpTarget snmpTarget) {

        target = snmpTarget.getTarget();

        snmpAgentConfig = snmpTarget.getSnmpAgentConfig();
    }

    public void start() throws AgentException {

        try {
            transport = new DefaultUdpTransportMapping();

            snmp = new Snmp(transport);

            createAuth(snmpAgentConfig, snmp);

            logger.debug("SNMP Agent : " + target.getAddress() + " added security info ");

            transport.listen();

            logger.debug("SNMP Agent : " + target.getAddress() + " UDP transport is listenening ");

        } catch (Exception e) {
            throw new AgentException(e);
        }

    }

    public void stop() throws AgentException {
        if (snmp != null) {
            try {
                snmp.close();
            } catch (IOException e) {
                throw new AgentException(e);
            }
        }
    }

    private void createAuth(SnmpAgentConfig snmpAgentConfig, Snmp snmp) {
        if (snmpAgentConfig instanceof SnmpAgentConfig_v3) {

            SnmpAgentConfig_v3 snmpAgentConfig_v3 = (SnmpAgentConfig_v3) snmpAgentConfig;

            OctetString username = new OctetString(snmpAgentConfig_v3.getUsername());
            OID authProtocol = snmpAgentConfig_v3.getAuthProtocol();
            OctetString authPassword = new OctetString(snmpAgentConfig_v3.getAuthPassword());
            OID privProtocol = null;
            OctetString privPassword = null;

            if (snmpAgentConfig_v3.getPrivProtocol() != null) {
                privProtocol = snmpAgentConfig_v3.getPrivProtocol();
            }

            if (snmpAgentConfig_v3.getPrivPassword() != null) {
                privPassword = new OctetString(snmpAgentConfig_v3.getPrivPassword());
            }

            logger.debug("SNMP Agent : " + target.getAddress() + " localEngineID : " + new OctetString(localEngineID));

            snmp.setLocalEngine(localEngineID, 0, 0);

            UsmUser usmUser = new UsmUser(username, authProtocol, authPassword, privProtocol, privPassword);

            snmp.getUSM().addUser(username, usmUser);

        }
    }

    private DefaultPDUFactory createPDU(int pduType, Target target, SnmpAgentConfig_v3 snmpAgentConfig, String context) {

        SnmpAgentConfig_v3 snmpAgentConfig_v3 = (SnmpAgentConfig_v3) snmpAgentConfig;

        OctetString contextName = null;

        if (context != null) {
            contextName = new OctetString(context);
        } else {
            contextName = new OctetString();
        }

        OctetString contextEngineID = null;

        if (snmpAgentConfig_v3.getContextAgentId() != null) {
            contextEngineID = new OctetString(snmpAgentConfig_v3.getContextAgentId());
        } else {
            contextEngineID = new OctetString();
        }

        return new DefaultPDUFactory(pduType, contextEngineID, contextName);

    }

    private DefaultPDUFactory createPDU(int pduType, Target target) {
        return new DefaultPDUFactory(pduType);
    }

    public Map<String, SNMPValue> doWalk(String oid) throws AgentException {

        logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "WALK" + " is started for OID : " + oid);

        Map<String, SNMPValue> result = new TreeMap<String, SNMPValue>();

        try {

            start();

            DefaultPDUFactory defaultPDUFactory = createPDU(PDU.GETNEXT, target);

            PDU pdu = defaultPDUFactory.createPDU(target);
            pdu.setRequestID(new Integer32(SNMPRequestIdHandler.getNextRequestId()));

            TreeUtils treeUtils = new TreeUtils(snmp, defaultPDUFactory);
            List<TreeEvent> events = treeUtils.getSubtree(target, new OID(oid));

            if (events == null || events.size() == 0) {
                logger.error("SNMP Agent : " + target.getAddress() + " Error: No result returned, table OID [" + oid + "] ");
                return result;
            }

            for (TreeEvent event : events) {
                if (event == null) {
                    continue;
                }
                if (event.isError()) {
                    logger.error("SNMP Agent : " + target.getAddress() + " Error: table OID [" + oid + "]  Error Status : " + event.getErrorMessage());
                    continue;
                }

                VariableBinding[] varBindings = event.getVariableBindings();
                if (varBindings == null || varBindings.length == 0) {
                    continue;
                }
                for (VariableBinding varBinding : varBindings) {
                    if (varBinding == null) {
                        continue;
                    }

                    result.put("." + varBinding.getOid().toString(), new SNMPValue(varBinding));
                }

            }

        } catch (Exception e) {

            long endTime = System.currentTimeMillis();
            long timeToRun = endTime - startTime;
            logger.error("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "WALK" + " is failed for OID : " + oid + " , Execution Time : " + timeToRun);
            throw new AgentException(e);
        } finally {
            stop();
        }

        long endTime = System.currentTimeMillis();
        long timeToRun = endTime - startTime;

        logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "WALK" + " is finished for OID : " + oid + " , Record Count : " + result.size() + ", Execution Time : " + timeToRun);

        return result;
    }

    public Map<String, SNMPValue> doWalk(String oid, String context) throws AgentException {

        logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "WALK" + " is started for OID : " + oid);

        Map<String, SNMPValue> result = new TreeMap<String, SNMPValue>();

        try {

            start();

            DefaultPDUFactory defaultPDUFactory = createPDU(PDU.GETNEXT, target, (SnmpAgentConfig_v3) snmpAgentConfig, context);

            PDU pdu = defaultPDUFactory.createPDU(target);
            pdu.setRequestID(new Integer32(SNMPRequestIdHandler.getNextRequestId()));

            TreeUtils treeUtils = new TreeUtils(snmp, defaultPDUFactory);
            List<TreeEvent> events = treeUtils.getSubtree(target, new OID(oid));

            if (events == null || events.size() == 0) {
                logger.error("SNMP Agent : " + target.getAddress() + " Error: No result returned, table OID [" + oid + "] , Context : " + context);
                return result;
            }

            for (TreeEvent event : events) {
                if (event == null) {
                    continue;
                }
                if (event.isError()) {
                    logger.error("SNMP Agent : " + target.getAddress() + " Error: table OID [" + oid + "] , Context : " + context + " Error Status : " + event.getErrorMessage());
                    continue;
                }

                VariableBinding[] varBindings = event.getVariableBindings();
                if (varBindings == null || varBindings.length == 0) {
                    continue;
                }
                for (VariableBinding varBinding : varBindings) {
                    if (varBinding == null) {
                        continue;
                    }

                    result.put("." + varBinding.getOid().toString(), new SNMPValue(varBinding));
                }

            }

        } catch (Exception e) {

            long endTime = System.currentTimeMillis();
            long timeToRun = endTime - startTime;
            logger.error("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "WALK" + " is failed for OID : " + oid + " , Context : " + context + ", Execution Time : " + timeToRun);
            throw new AgentException(e);
        } finally {
            stop();
        }

        long endTime = System.currentTimeMillis();
        long timeToRun = endTime - startTime;

        logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "WALK" + " is finished for OID : " + oid + " , Context : " + context + ", Record Count : " + result.size() + ", Execution Time : " + timeToRun);

        return result;
    }

    public SNMPValue get(String oid) throws AgentException {

        logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is started for OID : " + oid);

        long startTime = System.currentTimeMillis();

        SNMPValue result = null;

        try {

            start();

            DefaultPDUFactory defaultPDUFactory = createPDU(PDU.GET, target);

            PDU pdu = defaultPDUFactory.createPDU(target);

            pdu.add(new VariableBinding(new OID(oid)));
            pdu.setRequestID(new Integer32(SNMPRequestIdHandler.getNextRequestId()));

            logger.debug("SNMP Agent : " + target.getAddress() + " OID [" + oid + "] , PDU Request Id : " + pdu.getRequestID());

            ResponseEvent response = snmp.send(pdu, target, transport);

            // Process Agent Response
            if (response != null) {
                PDU responsePDU = response.getResponse();


                if (response.getError() != null) {
                    logger.info("SNMP Agent : " + target.getAddress() + " Response Error : " + response.getError());
                    response.getError().printStackTrace();
                }

                if (responsePDU != null) {
                    logger.debug("SNMP Agent : " + target.getAddress() + " OID [" + oid + "] , PDU Response Id : " + responsePDU.getRequestID());

                    int errorStatus = responsePDU.getErrorStatus();
                    int errorIndex = responsePDU.getErrorIndex();
                    String errorStatusText = responsePDU.getErrorStatusText();

                    if (errorStatus == PDU.noError) {
                        if (responsePDU.getVariableBindings() != null && responsePDU.getVariableBindings().size() > 0) {
                            result = new SNMPValue(responsePDU.getVariableBindings().get(0));
                        } else {
                            logger.error("SNMP Agent : " + target.getAddress() + " Error: Empty or null  OID [" + oid + "] ");
                        }
                    } else {
                        logger.error("SNMP Agent : " + target.getAddress() + " Error: Request Failed.  OID [" + oid + "] , Error Status : " + errorStatus);
                        throw new AgentException("SNMP Agent : " + target.getAddress() + " Error: Request Failed.  OID [" + oid + "] , Error Status : " + errorStatus);
                    }
                } else {
                    logger.error("SNMP Agent : " + target.getAddress() + " Error: Response PDU is null  OID [" + oid + "] ");
                    throw new AgentException("SNMP Agent : " + target.getAddress() + " Error: Response PDU is null  OID [" + oid + "] ");
                }
            } else {
                logger.error("SNMP Agent : " + target.getAddress() + " Error: Agent Timeout.  OID [" + oid + "] ");
                throw new AgentException("SNMP Agent : " + target.getAddress() + " Error: Agent Timeout.  OID [" + oid + "] ");
            }

        } catch (IOException e) {
            long endTime = System.currentTimeMillis();
            long timeToRun = endTime - startTime;
            logger.error("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is failed for OID : " + oid + " , Execution Time : " + timeToRun);
            throw new AgentException(e);
        } finally {
            stop();
        }

        long endTime = System.currentTimeMillis();
        long timeToRun = endTime - startTime;

        if (result != null) {
            logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is finished for OID : " + oid + " , Record Count : " + 1 + ", Execution Time : " + timeToRun);
        } else {
            logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is finished for OID : " + oid + " , Record Count : " + 0 + ", Execution Time : " + timeToRun);
        }

        return result;
    }

    public SNMPValue get(String oid, String context) throws AgentException {

        logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is started for OID : " + oid);

        long startTime = System.currentTimeMillis();

        SNMPValue result = null;

        try {

            start();

            DefaultPDUFactory defaultPDUFactory = createPDU(PDU.GET, target, (SnmpAgentConfig_v3) snmpAgentConfig, context);

            PDU pdu = defaultPDUFactory.createPDU(target);

            pdu.add(new VariableBinding(new OID(oid)));
            pdu.setRequestID(new Integer32(SNMPRequestIdHandler.getNextRequestId()));

            logger.debug("SNMP Agent : " + target.getAddress() + " OID [" + oid + "] , Context : " + context + ", PDU Request Id : " + pdu.getRequestID());

            ResponseEvent response = snmp.send(pdu, target, transport);

            // Process Agent Response
            if (response != null) {
                PDU responsePDU = response.getResponse();

                if (response.getError() != null) {
                    logger.info("SNMP Agent : " + target.getAddress() + " Response Error : " + response.getError() + " , Context : " + context);
                    response.getError().printStackTrace();
                }

                if (responsePDU != null) {
                    logger.debug("SNMP Agent : " + target.getAddress() + " OID [" + oid + "] , Context : " + context + ", PDU Response Id : " + responsePDU.getRequestID());

                    int errorStatus = responsePDU.getErrorStatus();
                    int errorIndex = responsePDU.getErrorIndex();
                    String errorStatusText = responsePDU.getErrorStatusText();

                    if (errorStatus == PDU.noError) {
                        if (responsePDU.getVariableBindings() != null && responsePDU.getVariableBindings().size() > 0) {
                            result = new SNMPValue(responsePDU.getVariableBindings().get(0));
                        } else {
                            logger.error("SNMP Agent : " + target.getAddress() + " Error: Empty or null  OID [" + oid + "] , Context : " + context);
                        }
                    } else {
                        logger.error("SNMP Agent : " + target.getAddress() + " Error: Request Failed.  OID [" + oid + "] , Context : " + context + ", Error Status : " + errorStatus);
                        throw new AgentException("SNMP Agent : " + target.getAddress() + " Error: Request Failed.  OID [" + oid + "] , Context : " + context + ", Error Status : " + errorStatus);
                    }
                } else {
                    logger.error("SNMP Agent : " + target.getAddress() + " Error: Response PDU is null  OID [" + oid + "] , Context : " + context);
                    throw new AgentException("SNMP Agent : " + target.getAddress() + " Error: Response PDU is null  OID [" + oid + "] , Context : " + context);
                }
            } else {
                logger.error("SNMP Agent : " + target.getAddress() + " Error: Agent Timeout.  OID [" + oid + "] , Context : " + context);
                throw new AgentException("SNMP Agent : " + target.getAddress() + " Error: Agent Timeout.  OID [" + oid + "] , Context : " + context);
            }

        } catch (IOException e) {
            long endTime = System.currentTimeMillis();
            long timeToRun = endTime - startTime;
            logger.error("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is failed for OID : " + oid + " , Context : " + context + ", Execution Time : " + timeToRun);
            throw new AgentException(e);
        } finally {
            stop();
        }

        long endTime = System.currentTimeMillis();
        long timeToRun = endTime - startTime;

        if (result != null) {
            logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is finished for OID : " + oid + " , Context : " + context + ", Record Count : " + 1 + ", Execution Time : " + timeToRun);
        } else {
            logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is finished for OID : " + oid + " , Context : " + context + ", Record Count : " + 0 + ", Execution Time : " + timeToRun);
        }

        return result;
    }

}

------------

IP2

new Thread(){

run{
     SNMPValue data = snmpFetcher.get(oid);
}


IP3

new Thread(){

run{

     SNMPValue data = snmpFetcher.get(oid);
}

最佳答案

我找到了解决方案。两个或多个主机的snmp代理上下文ID相同。
当使它们独特时,一切都很好。

10-05 23:05