跳到主要内容

SNMP v2c

Zeus.Protocols.Snmp 面向交换机、UPS、服务器、环境监控器和工业网关等带 SNMP Agent 的设备。当前支持 SNMP v2c 的单 OID GET/SET、常用变量类型、OID 点表采集、按点名写回、JSON 配置和虚拟 Agent 联调。

安装

dotnet add package Zeus.Communications
dotnet add package Zeus.Protocols.Snmp

SNMP 通常使用 UDP 161 端口。通道仍只负责收发字节,community、request-id 和 BER 编解码由 SnmpClient 处理。

无硬件联调

先用内存 Agent 验证点表和写回:

using Zeus;

var memory = new SnmpAgentMemory();
memory.SetGauge32("1.3.6.1.4.1.55555.1.1.0", 253, writable: true);
memory.SetText("1.3.6.1.4.1.55555.1.2.0", "rack-a", writable: true);

await using var app = ZeusHost.Create(builder =>
{
builder.AddAcquisition(TimeSpan.FromMilliseconds(500));
builder.AddVirtualChannel("snmp-link", new SnmpAgentResponder(memory));
builder.AddSnmp(
"agent",
"snmp-link",
points: map => map
.Gauge32("temperature", "1.3.6.1.4.1.55555.1.1.0", scale: 0.1)
.Writable("temperature")
.Text("location", "1.3.6.1.4.1.55555.1.2.0"));
});

await app.StartAsync();
Console.WriteLine(app.Points.Get<double>("temperature"));
await app.Points.WriteAsync("temperature", 18.6);

SnmpAgentMemory 预置了 sysDescr.0sysUpTime.0 和可写的 sysName.0,也可以通过 SetSetGauge32SetText 等方法添加现场 MIB。

连接真实设备

把虚拟通道替换成 UDP 客户端:

await using var app = ZeusHost.Create(builder =>
{
builder.AddUdpClient("snmp-link", "192.168.1.20", 161);
builder.AddSnmp(
"switch",
"snmp-link",
new SnmpOptions
{
Community = "public",
WriteCommunity = "private"
},
points: map => map
.Integer("ifNumber", "1.3.6.1.2.1.2.1.0")
.Counter32("ifInOctets", "1.3.6.1.2.1.2.2.1.10.1"));
});

await app.StartAsync();

设备若只允许读取,可以省略 WriteCommunity,并且不要把点标为可写。

直接读写

var agent = app.Devices.Get<SnmpDevice>("switch");

var name = await agent.Client.GetTextAsync("1.3.6.1.2.1.1.5.0");
var uptime = await agent.Client.GetAsync("1.3.6.1.2.1.1.3.0");
await agent.Client.SetAsync("1.3.6.1.2.1.1.5.0", SnmpValue.Text("edge-01"));

SnmpClient 会串行化同一通道上的请求,并校验 response request-id、PDU 类型、OID 和错误状态。

点表类型

APISNMP 类型Zeus 值
IntegerINTEGERlong,可选 scale 后为 double
Gauge32Gauge32uint,可选 scale 后为 double
Counter32Counter32uint,可选 scale 后为 double
TimeTicksTimeTicksuint,可选 scale 后为 double
TextOCTET STRINGUTF-8 string
OctetStringOCTET STRINGbyte[]
ObjectIdentifierOBJECT IDENTIFIEROID string
IpAddressIpAddressIPv4 string

数值点支持报警限。写回时 scale 会反向换算,例如采集值 25.3scale: 0.1 会向 Agent 写入原始值 253

JSON 配置

{
"acquisition": { "intervalMilliseconds": 500, "pollImmediately": true },
"channels": [
{ "name": "snmp-link", "type": "virtual", "responder": "snmp" }
],
"devices": [
{
"name": "agent",
"channel": "snmp-link",
"type": "snmp",
"snmpCommunity": "public",
"snmpWriteCommunity": "private",
"points": [
{
"name": "sysName",
"oid": "1.3.6.1.2.1.1.5.0",
"dataType": "text",
"writable": true
},
{
"name": "temperature",
"oid": "1.3.6.1.4.1.55555.1.1.0",
"dataType": "gauge32",
"scale": 0.1,
"lowAlarmLimit": 0,
"highAlarmLimit": 80
}
]
}
]
}

设备类型支持 snmpsnmp-v2csnmpv2c。虚拟通道的 responder 使用 snmp;真实设备则把通道改为 udp,填写设备 IP 和 161 端口。

排查

现象首先检查
请求超时设备 IP、UDP 161、防火墙、Agent 是否开启
authorizationErrorread/write community 或 ACL 不匹配
noSuchNameOID 不存在、实例后缀缺少 .0,或设备 MIB 不同
wrongTypedataType 与设备 MIB 的实际 ASN.1 类型不一致
点表没有值OID、数据类型、首次采集时间和点表错误快照

现场排查时打开通道报文追踪,确认请求和响应是否来自同一个设备,以及 response request-id 是否匹配。

下一步:JSON 配置UDP 通道通信报文追踪