You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SNMP4J使用SNMPv3请求超时问题排查与解决

问题描述

我正在开发一个Java交换机管理程序,目前仅尝试从交换机获取单个OID值。SNMPv2c版本的代码可以正常运行,但使用SNMPv3时始终返回Agent Timeout错误。不过使用相同参数的snmpget命令能正常得到结果,说明环境本身支持SNMPv3。

改用SNMPv2c并替换为CommunityTarget的代码可正常执行,因此怀疑问题出在SNMPv3的用户或目标配置上,但一直没找到解决办法。交换机配置没问题,因为net-snmp的控制台工具可以正常工作。

可用的snmpget命令

snmpget -v3 -l AuthPriv -u snmpuser -a MD5 -A "foo#Bar0815" -x DES -X "foo#Bar0815" 10.1.0.4:161 1.3.111.2.802.1.1.30.1.2.1.1.8.1.1    

无法运行的SNMPv3代码

public static void getAdminCycleTimeNumeratorv3() throws IOException
{
    String  ipAddress  = "10.1.0.4";
    String  port    = "161";
    String  oidValue  = "1.3.111.2.802.1.1.30.1.2.1.1.8.1.1";
    int     snmpVersion  = SnmpConstants.version3;
 
    TransportMapping transport = new DefaultUdpTransportMapping();
    Snmp snmp = new Snmp(transport);

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

    SecurityModels.getInstance().addSecurityModel(usm);

    transport.listen();

    // Set the target
    UserTarget target = new UserTarget();
    target.setAddress(GenericAddress.parse("udp:10.1.0.4/161"));
    target.setRetries(2);
    target.setTimeout(2000);
    target.setVersion(SnmpConstants.version3);
    target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
    target.setSecurityName(new OctetString("snmpuser"));

    // Set the security settings
    snmp.getUSM().addUser(
        new OctetString("snmpuser"),
        new UsmUser(
            new OctetString("snmpuser"),
            AuthMD5.ID,
            new OctetString("foo#Bar0815"),
            PrivDES.ID,
            new OctetString("foo#Bar0815")
        )
    );

    // Create PDU
    PDU pdu = new ScopedPDU();
    pdu.add(new VariableBinding(new OID(oidValue)));
    pdu.setType(PDU.GET);

    System.out.println("Sending SNMP Request");
    ResponseEvent response = snmp.get(pdu, target);

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

        if (responsePDU != null)
        {
            int errorStatus = responsePDU.getErrorStatus();
            int errorIndex = responsePDU.getErrorIndex();
            String errorStatusText = responsePDU.getErrorStatusText();

            if (errorStatus == PDU.noError)
            {
                System.out.println("Snmp Get Response = " + responsePDU.getVariableBindings());
            }
            else
            {
                System.out.println("Error: Request Failed");
                System.out.println("Error Status = " + errorStatus);
                System.out.println("Error Index = " + errorIndex);
                System.out.println("Error Status Text = " + errorStatusText);
            }
        }
        else
        {
            System.out.println("Error: Response PDU is null");
        }
    }
    else
    {
        System.out.println("Error: Agent Timeout");
    }
     
    snmp.close();
}
解决方法

问题出在SecurityProtocols实例的初始化上,需要手动添加所需的认证协议,再将该实例传入USM。修改后的关键代码如下:

// 先创建SecurityProtocols实例并添加认证协议
SecurityProtocols securityProtocols = SecurityProtocols.getInstance();
securityProtocols.addAuthenticationProtocol(new AuthSHA());
securityProtocols.addAuthenticationProtocol(new AuthMD5());

// 将配置好的实例传入USM
USM usm = new USM(
    securityProtocols,
    new OctetString(MPv3.createLocalEngineID()),
    0
);

SecurityModels.getInstance().addSecurityModel(usm);

内容的提问来源于stack exchange,提问作者Astor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 08:57:24