1. 前言
SNMP(Simple Network Management Protocol)是网络设备、服务器、工业电源、通信电源、UPS、充电桩的通用监控协议。
不管是后端监控、嵌入式开发、Android 现场调试,还是机房运维,SNMP 都是必备技能。
本文内容:
原理 + 报文 + 架构 + 流程图
公共标准 OID
主流厂商 OID(华为、维谛、中兴、英可瑞、麦格米特)
麦格米特 Megmeet OID 超详细版(主力案例)
Java 后台采集代码
Android APP 采集代码
可直接用于项目 / 博客 / 笔记 / 面试
2. SNMP 基础(快速回顾)
2.1 端口
UDP 161:Get / Set(查询/配置)
UDP 162:Trap 主动告警
2.2 核心角色
NMS:网管上位机
Agent:设备代理
MIB:树形管理库
OID:每个参数的唯一编号
2.3 5 种核心报文
GetRequest:查单个
GetNextRequest:遍历
GetBulk:批量获取
SetRequest:设置参数
GetResponse:回复
Trap:设备主动上报告警
2.4 三个版本
v1:老、不安全
v2c:最常用(团体名 public/private)
v3:安全、认证、加密
3. 公共标准 MIB OID(所有设备通用)
系统信息
1.3.6.1.2.1.1.1.0sysDescr 系统描述1.3.6.1.2.1.1.3.0sysUpTime 运行时间1.3.6.1.2.1.1.5.0sysName 设备名称
接口信息
1.3.6.1.2.1.2.1.0网口数量1.3.6.1.2.1.2.2.1.2端口描述1.3.6.1.2.1.2.2.1.6MAC 地址1.3.6.1.2.1.2.2.1.8端口状态 up/down
64 位流量
1.3.6.1.2.1.31.1.1.1.6入流量1.3.6.1.2.1.31.1.1.1.10出流量
4. 主流电源/工控厂商 OID
常见厂家
4.1 华为 Huawei
根 OID:
1.3.6.1.4.1.2011常见监控:
设备型号
单板状态
电压、电流
温度、风扇
告警
4.2 维谛 Vertiv(原艾默生)
根 OID:
1.3.6.1.4.1.21238监控:
UPS 状态
输入输出电压
电池容量
市电状态
4.3 中兴 ZTE
根 OID:
1.3.6.1.4.1.3902监控:
通信电源
模块电流电压
机柜环境
4.4 英可瑞 Ingress
根 OID:
1.3.6.1.4.1.36578主要用于:
充电桩电源
输出电压
输出电流
模块温度
5. 麦格米特 Megmeet OID
5.1 麦格米特 官方根 OID
1.3.6.1.4.1.260675.2 设备基本信息
1.3.6.1.4.1.26067.1.1.1.0设备型号1.3.6.1.4.1.26067.1.1.2.0固件版本1.3.6.1.4.1.26067.1.1.3.0序列号1.3.6.1.4.1.26067.1.1.4.0厂商名称
5.3 交流输入 AC INPUT
1.3.6.1.4.1.26067.1.2.1.0A 相电压1.3.6.1.4.1.26067.1.2.2.0B 相电压1.3.6.1.4.1.26067.1.2.3.0C 相电压1.3.6.1.4.1.26067.1.2.4.0电网频率1.3.6.1.4.1.26067.1.2.5.0总输入电流
5.4 直流输出 DC OUTPUT
1.3.6.1.4.1.26067.1.3.1.0输出电压1.3.6.1.4.1.26067.1.3.2.0输出电流1.3.6.1.4.1.26067.1.3.3.0输出功率1.3.6.1.4.1.26067.1.3.4.0限流点1.3.6.1.4.1.26067.1.3.5.0输出电量
5.5 环境监测
1.3.6.1.4.1.26067.1.4.1.0内部温度1.3.6.1.4.1.26067.1.4.2.0环境温度1.3.6.1.4.1.26067.1.4.3.0湿度1.3.6.1.4.1.26067.1.4.4.0风扇转速
5.6 告警状态(非常重要)
1.3.6.1.4.1.26067.1.5.1.0总告警(0正常/1告警)1.3.6.1.4.1.26067.1.5.2.0过压告警1.3.6.1.4.1.26067.1.5.3.0欠压告警1.3.6.1.4.1.26067.1.5.4.0过流告警1.3.6.1.4.1.26067.1.5.5.0过温告警1.3.6.1.4.1.26067.1.5.6.0风扇故障1.3.6.1.4.1.26067.1.5.7.0交流掉电
5.7 电池信息(UPS/电源系统)
1.3.6.1.4.1.26067.1.6.1.0电池电压1.3.6.1.4.1.26067.1.6.2.0电池电流1.3.6.1.4.1.26067.1.6.3.0电池温度1.3.6.1.4.1.26067.1.6.4.0电池剩余容量 %
6. SNMP 完整工作流程(图文逻辑版)
6.1 Get 查询流程
NMS 构造 GetRequest
带上 IP、团体名、OID
发 UDP 161
设备 Agent 解析
查询 MIB 库
返回 GetResponse
解析数据展示
6.2 Trap 告警流程
设备产生故障:过温/过压/掉电
Agent 主动发 Trap
目标 NMS 的 162 端口
网管系统接收、告警、记录
7. Java 实现 SNMP(完整工具类)
Maven
<dependency>
<groupId>org.snmp4j</groupId>
<artifactId>snmp4j</artifactId>
<version>2.8.3</version>
</dependency>SnmpUtil.java
import org.snmp4j.*;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.*;
import org.snmp4j.transport.DefaultUdpTransportMapping;
public class SnmpUtil {
private static final int VERSION = SnmpConstants.version2c;
private static final String COMMUNITY = "public";
public static String get(String ip, String oid) throws Exception {
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString(COMMUNITY));
target.setAddress(GenericAddress.parse("udp:" + ip + "/161"));
target.setVersion(VERSION);
target.setTimeout(2000);
target.setRetries(1);
TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
transport.listen();
Snmp snmp = new Snmp(transport);
PDU pdu = new PDU();
pdu.add(new VariableBinding(new OID(oid)));
pdu.setType(PDU.GET);
ResponseEvent resp = snmp.send(pdu, target);
PDU response = resp.getResponse();
String result = "timeout";
if (response != null) {
result = response.get(0).getVariable().toString();
}
snmp.close();
transport.close();
return result;
}
// 麦格米特示例
public static void main(String[] args) throws Exception {
String ip = "192.168.1.100";
String tempOid = "1.3.6.1.4.1.26067.1.4.1.0";
System.out.println("麦格米特温度:" + get(ip, tempOid));
}
}8. Android 实现 SNMP(完整可运行)
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />build.gradle
implementation 'org.snmp4j:snmp4j:2.8.3'SnmpAndroidManager.kt
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.snmp4j.*
import org.snmp4j.event.ResponseEvent
import org.snmp4j.mp.SnmpConstants
import org.snmp4j.smi.*
import org.snmp4j.transport.DefaultUdpTransportMapping
class SnmpAndroidManager {
fun get(
ip: String,
oid: String,
callback: (String) -> Unit
) {
GlobalScope.launch(Dispatchers.IO) {
try {
val target = CommunityTarget().apply {
community = OctetString("public")
address = GenericAddress.parse("udp:$ip/161")
version = SnmpConstants.version2c
timeout = 2000
retries = 1
}
val transport = DefaultUdpTransportMapping()
transport.listen()
val snmp = Snmp(transport)
val pdu = PDU()
pdu.add(VariableBinding(OID(oid)))
pdu.type = PDU.GET
val respEvent: ResponseEvent = snmp.send(pdu, target)
val response = respEvent.response
val result = response?.get(0)?.variable.toString() ?: "timeout"
snmp.close()
transport.close()
callback(result)
} catch (e: Exception) {
callback(e.message ?: "error")
}
}
}
}Activity 中调用(麦格米特案例)
val snmp = SnmpAndroidManager()
snmp.get("192.168.1.100", "1.3.6.1.4.1.26067.1.3.1.0") { result ->
runOnUiThread {
tv_voltage.text = "麦格米特输出电压:$result V"
}
}SNMP 协议解析
https://lautung.com/archives/BZwneKby