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

SNMP GETBULK问题:只能获取部件记录(例如59条记录,但超过100条记录),snmp,snmp4j,Snmp,Snmp4j,我想通过snmp GETBULK获取路由器的接口信息,但是当我使用它时,只返回了部分记录 代码如下: public static void main(String[] args) throws IOException, InterruptedException { Snmp snmp = new Snmp(new DefaultUdpTransportMapping()); snmp.listen(); CommunityTarget target = new Comm

我想通过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());
        }
    }
}
publicstaticvoidmain(String[]args)抛出IOException、interruptedeexception{
Snmp=新的Snmp(新的DefaultUDPTTransportMapping());
snmp.listen();
CommunityTarget=新的CommunityTarget();
setCommunity(新的八位字符串(“public”);
setVersion(SnmpConstants.version2c);
target.setAddress(新的UdpAddress(“127.0.0.1/161”);
target.setTimeout(3000);//3s
目标。设置重试次数(1);
PDU PDU=新的PDU();
pdu.setType(pdu.GETBULK);
pdu.设置最大重复次数(200);
pdu.setNonRepeaters(0);
pdu.add(新变量绑定(新OID(“1.3.6.1.2.1.31.1.1.1”));
ResponseEvent ResponseEvent=snmp.send(pdu,目标);
PDU response=responseEvent.getResponse();
如果(响应==null){
System.out.println(“超时…”);
} 
其他的
{
if(response.getErrorStatus()==PDU.noError)
{

Vector您的响应有多大?请记住-getbulk响应必须适合单个UDP数据包。这是65535字节的绝对限制-或者如果您有可能小到1500字节的MTU限制。

我只想指出,原始海报有一个解决方案:使用GETNEXT而不是getbulk,您将获得所有只有当您的返回值在指定的PP大小内时,GETBULK才会对您起作用。

这是预期的行为,可能是由于一些原因

引用(重点):

[…]接收SNMP实体生成一个响应PDU,其最多为请求所传递的请求变量绑定总数

[…]虽然响应PDU中变量绑定的最大数量以N+(M*R)为界,但出于以下三个原因之一,可以使用较少数量的变量绑定(可能为零)生成响应

  • 如果封装响应PDU的消息的大小 包含请求数量的变量绑定将是 大于本地约束或最大消息 发起者的大小,然后使用 变量绑定的数量较少。此较少的数量是 具有某些变量的有序变量绑定集 集合末尾的绑定已删除,因此 封装响应PDU的消息大约为 等于但不大于局部约束或 原始发件人的最大邮件大小。请注意 移除的变量绑定的数量与值没有关系 属于N、M或R

  • 还可以使用较少数量的响应来生成响应 变量绑定,如果迭代i的某个值 大于零且小于或等于M,则 生成的变量绑定的值字段设置为 在这种情况下,变量绑定可能是 在(N+(i*R))-th变量绑定后截断

  • 如果一个请求的处理包含多个 重复需要大量的训练 处理时间超过正常请求,然后是命令响应程序 应用程序可以终止请求,但终止时间少于完整时间 重复次数,前提是至少需要一次重复 完成

  • [……]

    在您的情况下,您很可能超过了最大消息大小

    如果得到的对象少于所需的对象,则可以从停止的位置开始执行另一个GetBulk请求。(这与在C代码中处理TCP/IP套接字的方式相同-您必须依次保持
    read()
    ing,直到获得所需的一切。)


    例如,Net SNMP的
    snmptable
    等实现(可以指示使用GetBulk的表遍历器)将一直执行此操作,直到到达表的末尾。

    那么解决方案是什么?如何获取更多数据?@darrickc将您的请求分解为几个单独的请求。或者限制对getbulk请求的最大响应数。这只是部分有帮助。返回的数据量确实存在上限,但如果您使用的是GetBulk,那么您这样做可能是出于一个原因:通常最好继续对剩余对象执行GetBulk请求(根据需要执行多个!),而不是一次只对一个对象执行请求(高效!)。事实上,如果在请求中插入足够多的varbind,则GetNext也会受到这些约束!