GetBulk() 方法
GetBulk()方法是对GetNext()方法的二度封装,GetNext()方法返回的是传入的oid的下一个对象,而GetBulk方法则是返回传入的oid的接下来的N个对象。
通过GetBulk传入的oid,SNMP代理会根据传入的参数去循环取值,构造PDU,但是,如果符合传入的oid的对象的数量超过了一个PDU所能容纳的限度,SNMP代理会截断数据包,换言之返回的数据就不全。
为了获取完整的数据,就要对单个PDU装不下这种情况进行循环处理,但由于其实际上是使用了GetNext()方法,所以还需要调用者给一个循环结束的标识,控制循环在取到所有预期的数据后及时break,否则调用GetBulk()的循环可以一直无限循环,直到整棵树都被被遍历完为止。
package main
import (
"fmt"
// "log"
"time"
"github.com/gosnmp/gosnmp"
)
// 定义一个自己的Init函数
func InitSnmpPoller(TargetIP string) gosnmp.GoSNMP {
g := gosnmp.GoSNMP{}
g.Target = TargetIP
g.Community = "public"
g.Version = gosnmp.Version2c
g.Transport = "udp"
g.Timeout = 2 * time.Second
g.Retries = 3
g.MaxOids = gosnmp.MaxOids
g.Port = 161
return g
}
// 处理返回结果的函数
func processSNMPResults(pdu gosnmp.SnmpPDU) error {
switch pdu.Type {
case gosnmp.OctetString:
bytes := pdu.Value.([]byte)
fmt.Printf("string: %s\n", string(bytes))
default:
fmt.Printf("number: %d\n", gosnmp.ToBigInt(pdu.Value))
}
return nil
}
// 使用Get接口的函数。
func SnmpGetOperation(g *gosnmp.GoSNMP, oids []string) {
result, err := g.Get(oids)
if err != nil {
panic(err.Error())
}
for i, variable := range result.Variables {
fmt.Printf("%d-> oid:%s = ", i, variable.Name)
processSNMPResults(variable)
}
}
//GetNext()调用的简单封装和单元测试
func SnmpGetNextOperation(g *gosnmp.GoSNMP, oids []string) {
result, err := g.GetNext(oids)
if err != nil {
panic(err.Error())
}
for i, variable := range result.Variables {
fmt.Printf("%d-> oid:%s = ", i, variable.Name)
processSNMPResults(variable)
}
}
// Bulk()的调用
func SnmpGetBulkOperation(g *gosnmp.GoSNMP, oids []string, maxRepetitions uint32) error {
result, err := g.GetBulk(oids, 0, maxRepetitions)
if err != nil {
panic(err.Error())
}
fmt.Println(len(result.Variables))
for i, variable := range result.Variables {
fmt.Printf("%d-> oid:%s = ", i, variable.Name) //variable.Name is oid
processSNMPResults(variable)
}
return nil
}
// Walk()的调用
func SnmpWalkOperation(g *gosnmp.GoSNMP, oid string) {
err := g.Walk(oid, processSNMPResults)
if err != nil {
panic(err.Error())
}
}
func main() {
oids := []string{
// "1.3.6.1.2.1.1.4.0",
// "1.3.6.1.2.1.1.1.0",
"1.3.6.1.2.1.2.2.1.2",
}
g := InitSnmpPoller("127.0.0.1")
g.Connect()
defer g.Conn.Close()
SnmpGetOperation(&g, oids)
// SnmpGetNextOperation(&g, oids)
// err := SnmpGetBulkOperation(&g, oids, 50)
// if err != nil {
// fmt.Println(err.Error())
// }
rootoid := "1.3.6.1.2.1.2.2.1.1"
SnmpWalkOperation(&g, rootoid)
}