SNMP GETBULK问题:只能获取部件记录(例如59条记录,但有超过100条记录)

时间:2013-07-18 09:20:41

标签: snmp snmp4j

我想通过snmp GETBULK获取路由器的接口信息,但是当我使用它时,只返回部分记录。

代码如下:

public static void main(String[] args) throws IOException, InterruptedException {
    Snmp snmp = new Snmp(new DefaultUdpTransportMapping());
    snmp.listen();

    CommunityTarget target = new CommunityTarget();
    target.setCommunity(new OctetString("public"));
    target.setVersion(SnmpConstants.version2c);
    target.setAddress(new UdpAddress("127.0.0.1/161"));
    target.setTimeout(3000);    //3s
    target.setRetries(1);

    PDU pdu = new PDU();
    pdu.setType(PDU.GETBULK);
    pdu.setMaxRepetitions(200); 
    pdu.setNonRepeaters(0);
    pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.31.1.1.1.1"))); 

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

    if (response == null) {
        System.out.println("TimeOut...");
    } 
    else 
    {
        if (response.getErrorStatus() == PDU.noError) 
        {
            Vector<? extends VariableBinding> vbs = response.getVariableBindings();
            for (VariableBinding vb : vbs) {
                System.out.println(vb + " ," + vb.getVariable().getSyntaxString());
            }
        } 
        else 
        {
            System.out.println("Error:" + response.getErrorStatusText());
        }
    }
}

执行后,会返回59条记录,但如果我使用GETNEXT获取它们,则会返回约197条记录。

有什么想法吗?

希望有人能帮助我,提前谢谢。

3 个答案:

答案 0 :(得分:3)

您的回复有多大?请记住 - getbulk响应必须适合单个UDP数据包。这是65,535字节的绝对限制 - 或者如果你有MTU限制可能只有1,500字节。

答案 1 :(得分:0)

我想指出的是,原始海报具有解决方案:使用GETNEXT而不是GETBULK,您将获得所有记录。如果您的退货在PP大小以内,GETBULK将只为您服务。指定。

答案 2 :(得分:0)

这是预期的行为,可能由于某些原因而发生。

引用RFC 3416 §4.2.3 "The GetBulkRequest-PDU"(强调我的意思):

  

[..]接收方SNMP实体产生一个响应PDU,其中最多由请求传达的请求变量绑定总数。

     

[..]虽然Response-PDU中的变量绑定的最大数目由N +(M * R)限制,但是对于三个变量中的任意一个,可能会生成较少数量的变量绑定(可能为零)来生成响应原因。

     
      
  1. 如果封装Response-PDU的消息的大小        包含请求数量的变量绑定将是        大于本地约束或最大消息数        发起者的大小,然后使用        较少的变量绑定。这个较小的数字是        与某些变量绑定的变量绑定的有序集合        集的末尾的绑定被删除,使得        封装Response-PDU的消息大约是        等于但不大于局部约束或        发起者的最大邮件大小。注意号码        删除的变量绑定数量与值无关        N,M或R。

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

  4.   
  5. 在处理请求的过程中,        重复需要大量的        处理时间比正常请求要长,然后是命令响应者        应用程序终止请求的次数可能少于全部请求        重复次数,如果至少有一次重复是        完成。

  6.   
     

[..]

以您为例,您很可能超出了最大邮件大小。

如果获得的对象少于所需数量,则可以从上次中断的地方开始执行另一个 GetBulk 请求。 (这与您使用C代码处理TCP / IP套接字的方式相同-您必须依次保持read()到拥有所需的一切为止。)

例如,诸如Net-SNMP的snmptable(可以指示使用 GetBulk 的表遍历器)之类的实现将执行此操作,直到到达表末尾为止。 / p>