我正在使用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个条目。
答案 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()
开始。