使用snmp协议获取和管理摄像头设备信息

snmp协议

简单网络管理协议,专门设计用于在 IP 网络管理网络节点(服务器、工作站、路由器、交换机及HUBS等)的一种标准协议,属于应用层协议, 大部分摄像头支持snmp管理协议的1,2,3版本,本身管理也是使用cs架构,如下图所示:
使用snmp协议获取和管理摄像头设备信息_第1张图片

获取摄像头基本信息

snmpwalk -v 2c -c public 192.168.0.55 1
使用snmp协议获取和管理摄像头设备信息_第2张图片
图中可以看到192.168.0.55 是hik 海康摄像头,支持h264和h265

cpu获取

使用snmpwalk 获取 192.168.0.129 的 cpu利用率
snmpwalk -v 2c -c public 192.168.0.129 .1.3.6.1.2.1.25.3.3.1.2
使用snmp协议获取和管理摄像头设备信息_第3张图片
可以看到 本身我的机器有16核心,每一个核心都有自己的cpu利用率

内存

snmpwalk -v 2c -c public 192.168.0.129 .1.3.6.1.2.1.25.2.2.0
使用snmp协议获取和管理摄像头设备信息_第4张图片
可以看到192.168.0.129 有16G 内存

java snmp4j

package com.test;

import org.snmp4j.*;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.DefaultPDUFactory;
import org.snmp4j.util.TableEvent;
import org.snmp4j.util.TableUtils;

import java.io.IOException;
import java.util.List;

public class SnmpDemo2 {

public static void main(String[] args) {
creatSnmp();
}

public static void creatSnmp() {

TransportMapping transport = null;
Snmp snmp = null;
CommunityTarget target = null;
try {
transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);//创建snmp
snmp.listen();//监听消息
target = new CommunityTarget();
target.setCommunity(new OctetString("public"));//社区名称
target.setRetries(3);//连接次数
target.setAddress(GenericAddress.parse("udp:172.18.12.96/161"));//监控的主机
target.setTimeout(8000);//
target.setVersion(SnmpConstants.version2c);
String memory = collectMemory(snmp, target);
System.out.println("内存使用率为:" + memory);
String cpu = collectCPU(snmp, target);
System.out.println("CPU利用率为:" + cpu);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (transport != null)
transport.close();
if (snmp != null)
snmp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

//获取内存相关信息
public static String collectMemory(Snmp snmp, CommunityTarget target) {
String memory = null;
String[] oids = {"1.3.6.1.2.1.25.2.3.1.2", //type 存储单元类型
"1.3.6.1.2.1.25.2.3.1.3", //descr
"1.3.6.1.2.1.25.2.3.1.4", //unit 存储单元大小
"1.3.6.1.2.1.25.2.3.1.5", //size 总存储单元数
"1.3.6.1.2.1.25.2.3.1.6"}; //used 使用存储单元数;
String PHYSICAL_MEMORY_OID = "1.3.6.1.2.1.25.2.1.2";//物理存储
try {
TableUtils tableUtils = new TableUtils(snmp, new DefaultPDUFactory(PDU.GETBULK));
OID[] columns = new OID[oids.length];
for (int i = 0; i < oids.length; i++)
columns[i] = new OID(oids[i]);
List<TableEvent> list = tableUtils.getTable(target, columns, null, null);
for (TableEvent event : list) {
VariableBinding[] values = event.getColumns();
if (values == null) continue;
int unit = Integer.parseInt(values[2].getVariable().toString());//unit 存储单元大小
int totalSize = Integer.parseInt(values[3].getVariable().toString());//size 总存储单元数
int usedSize = Integer.parseInt(values[4].getVariable().toString());//used 使用存储单元数
String oid = values[0].getVariable().toString();
if (PHYSICAL_MEMORY_OID.equals(oid)) {
memory = (long) usedSize * 100 / totalSize + "%";
}
}

} catch (Exception e) {
e.printStackTrace();
}
return memory;
}

//获取cpu使用率
public static String collectCPU(Snmp snmp, CommunityTarget target) {
String cpu = null;
String[] oids = {"1.3.6.1.2.1.25.3.3.1.2"};
try {
TableUtils tableUtils = new TableUtils(snmp, new DefaultPDUFactory(PDU.GETBULK));
OID[] columns = new OID[oids.length];
for (int i = 0; i < oids.length; i++)
columns[i] = new OID(oids[i]);
List<TableEvent> list = tableUtils.getTable(target, columns, null, null);
int percentage = 0;
for (TableEvent event : list) {
VariableBinding[] values = event.getColumns();
if (values != null)
percentage += Integer.parseInt(values[0].getVariable().toString());
}
cpu = percentage / list.size() + "%";
} catch (Exception e) {
e.printStackTrace();
}
return cpu;
}


}

在vscode中写入依赖

<dependency>
<groupId>org.snmp4jgroupId>
<artifactId>snmp4jartifactId>
<version>2.6.2version>
dependency>

使用nodejs

使用net-snmp模块去walk,实际上net-snmp还是c写的一套东西,以下程序使用每隔2秒探测一次,程序只是为示例,可以探测摄像头的各个参数

var os = require('os');
var snmp = require ("net-snmp");
var moment = require('moment');
const nodemon = require("nodemon");

var session = snmp.createSession ("192.168.0.129", "public");

var items = [
	//{name: 'percent', oid: '1.3.6.1.4.1.39165.1.11.0'}
	{name: 'cpu', oid: '1.3.6.1.2.1.25.3.3.1.2'}
	
];


function doneCb(error) {
    if (error)
        console.error(error.toString());
}

 
function feedCb(varbinds) {
    for (var i = 0; i < varbinds.length; i++) {
        if (snmp.isVarbindError(varbinds[i]))
            console.error(snmp.varbindError(varbinds[i]));
        else
            console.log(varbinds[i].oid + "|" + varbinds[i].value);
    }
}

setInterval(()=>{
	let nowTime = moment().format('YYYY-MM-DD HH:mm:ss');
	console.log('当前时间为:', nowTime);
	session.walk(items[0].oid, 1, feedCb, doneCb);
}, 2000);

当然也可以使用其他如python, go 语言用同样的道理去做,建议:
像这类程序最好不要用c++ 做,反而是像java, node,等这种语言比较简单,本身简单网络管理协议相对具体传输媒体协议来说,确实是比较“简单”的,简单还是要加引号的,并不涉及非常高的性能问题。

你可能感兴趣的:(nodejs,音视频和c++,java,物联网,网络,java,开发语言)