GETBULK SNMP4J请求

时间:2017-05-23 10:28:57

标签: java snmp snmp4j

我正在使用snmp4j尝试对远程代理执行SNMP功能。由于我们无法控制的一些限制,我需要执行GETBULK以在很短的时间内获得一个大表。

我目前的实施:

public Map<String, String> doGetBulk(@NotNull VariableBinding... vbs)  
        throws IOException {

        Map<String, String> result = new HashMap<>();
        Snmp snmp = null;

        try {

            // Create TransportMapping and Listen
            TransportMapping transport = new DefaultUdpTransportMapping();
            snmp = new Snmp(transport);
            transport.listen();

            PDU pdu = new PDU();
            pdu.setType(PDU.GETBULK);
            pdu.setMaxRepetitions(200);
            pdu.setNonRepeaters(0);
            pdu.addAll(vbs);

            ResponseEvent responseEvent = snmp.send(pdu, this.target);
            PDU response = responseEvent.getResponse();

            // Process Agent Response
            if (response != null) {
                for(VariableBinding vb : response.getVariableBindings()) {
                    result.put("." + vb.getOid().toString(), vb.getVariable().toString());
                }
            } else {
                LOG.error("Error: Agent Timeout... ");
            }

        } catch (NullPointerException ignore) {
            // The variable table is null
        } finally {
            if (snmp != null) snmp.close();
        }
        return result;
    }

然而,当我知道有5000+时,这只会返回100个结果。我知道我不能超过PDU大小所以我有这样的问题,响应被截断为100块,但我无法弄清楚如何获得一个句柄级联请求以获得接下来的100个条目。

3 个答案:

答案 0 :(得分:0)

使用MaxRepetitions&gt;是不好的做法。 100由于TCP / IP数据包碎片和UDP的性质,不保证数据包的顺序。因此,大多数SNMP框架和代理都有这样的内置限制。

答案 1 :(得分:0)

RFC文档中已有所有详细信息,

https://tools.ietf.org/html/rfc1905

4.2.3告诉代理方如何处理GET BULK请求,

  

响应PDU中的最大变量绑定数为
  以N +(M * R)为界,可以用较小的数字生成响应   三个中的任何一个的变量绑定数(可能为零)   的原因。

     

(1)如果消息的大小封装了Response-PDU        包含所请求数量的变量绑定将是        大于本地约束或最大消息大小        对于发起者而言,响应是以较小的方式生成的        变量绑定的数量。这个较小的数字是有序集        变量绑定与末尾的一些变量绑定        删除集合,以便封装消息的大小        Response-PDU大约等于但不大于        本地约束或最大消息大小        鼻祖。请注意,删除的变量绑定的数量        与N,M或R的值无关。

     

(2)也可以用较少的数量生成响应   变量        如果对于迭代i的某个值,则绑定,使得i更大        比零和小于或等于M,即所有生成的        变量绑定的value字段设置为`endOfMibView'。        在这种情况下,变量绑定可能在(N +之后)被截断        (i * R)) - 变量绑定。

     

(3)如果处理请求有很多   重复        需要比a更大的处理时间        正常请求,然后代理可以用less来终止请求        比完整的重复次数,提供至少一个        重复完成。

关于如何进行一系列正确的GET BULK操作以查询所需的所有数据,您可以参考第4.2.3.1节中的示例。

答案 2 :(得分:0)

您已将最大重复次数设置为200,即服务器最多可向您发送200行。所以一方面,你永远不会超过200行(至少5000行或更多)。另一方面,服务器可能决定向您发送较少的行,这实际上是服务器的选择;你告诉他你能够处理什么。

通常你最多要求10-50行。 (顺便说一句:有很多服务器都有错误的SNMP实现,你设置的最大重复次数越高,你得到的东西就越高。)

所以你必须按行集请求行集。由于您可能不想自己实现,我建议您使用TableUtils类。只需从getTable()开始。