java snmp协议 获取数据
最近工作内容涉及到snmp协议相关内容,由于第一次接触,又没有实际的环境测试,写出来的东西自己都不确定能不能用,直到最近有环境后,花了一段时间才搞定。
写下这篇文章,只是给和我之前一样的小白指点一波,让其他人不必再和我一样被折磨一遍,如果大佬看到我哪里有写错,也请指正。
这里首先强调一点,snmp协议,我java代码这边是作为接收者,而提供信息的是机器设备,但我想通过snmp协议获取数据,是由我发起,然后接收返回的参数。
我这边对接的对象是华为交换机,我这边由参考一篇文章,可以根据下面这篇的文章找到对接的机器的型号,再找到oid
http://t.zoukankan.com/zhenwei66-p-10473121.html
然后网上还可以取找一个叫MIB Browser的工具,这个玩意也可以测试snmp
下面是我的java代码,我会逐一解释其中的内容
首先是第一个方法,我是把snmp协议需要的参数全部丢到json文件中了,这个方法是用来处理json文件读取的,然后把读到的信息转成对象,转换的是最下面两个类,再写入snmp配置,两个入参,第一个是json文件中的品牌,第二个是你snmp协议中的请求例如:get,getnext这些。
private static final Logger logger = LoggerFactory.getLogger(SnmpUtil.class);private static final String jsonFile = "Snmp.json";private Snmp snmp;/*** 根据入参,选择json文件内容进行snmp协议发送* @author 汪彪* @date 2022/7/22 15:23* @param name* @param pduType* @return java.util.List<jee.pluses.com.vo.huawei.Mib>*/public List<Mib> sendSnmp(String name,Integer pduType) throws IOException {//读取Snmp.json文件中数据String js = null;js = readJson(jsonFile);//将读取到的字符串实例化成对象JSONObject jasonDate = JSONObject.parseObject(js);JSONArray pageData = (JSONArray) jasonDate.get("snmp");List<SnmpVo> snmpVoList = JSONObject.parseArray(pageData.toString(), SnmpVo.class);for (SnmpVo snmpVo : snmpVoList) {if (name.equals(snmpVo.getName())){return sendSnmp(snmpVo, pduType);}}return null;}
这个方法是配置snmp协议属性用的,在这里调用其他方法生成snmp,pdu,target,然后调用send方法就可以收获你想要的值
/*** 获取snmp数据,根据json文件内容* @author 汪彪* @date 2022/7/22 15:22* @param snmpVo* @param pduType* @return java.util.List<jee.pluses.com.vo.huawei.Mib>*/private List<Mib> sendSnmp(SnmpVo snmpVo,Integer pduType) throws IOException {initSnmp(snmpVo);PDU pdu = setPDU(snmpVo, pduType);Target target = setTarget(snmpVo);ResponseEvent responseEvent = snmp.send(pdu, target);PDU response = responseEvent.getResponse();if (response == null){return null;}List<Mib> mib = snmpVo.getMib();for (Mib m : mib) {Variable variable = response.getVariable(new OID(m.getOid()));m.setValue(String.valueOf(variable));}return mib;}
这里是target的设置,由于我对接的设备是版本为2的,所以版本3行不行,我这里还不确定。但版本1和2 都是一样的,只需要设置地址,和团体名称,加设置版本,基本就可以了
/*** target设置,版本3未测试* @author 汪彪* @date 2022/7/21 17:12* @param snmpVo* @return org.snmp4j.Target*/private Target setTarget(SnmpVo snmpVo){Address targetAddress = GenericAddress.parse("udp:" + snmpVo.getTargetIp() + "/" + snmpVo.getTargetPort());Target target = null;//SNMP的不同版本if (snmpVo.getVersion() == SnmpConstants.version3) {// 添加用户OctetString userName = new OctetString(snmpVo.getUserName());OctetString userAuthPassword = new OctetString(snmpVo.getUserAuthPassword());OctetString userPrivatePassword = new OctetString(snmpVo.getUserPrivPassword());UsmUser usmUser = new UsmUser(userName, AuthMD5.ID,userAuthPassword , PrivDES.ID,userPrivatePassword);snmp.getUSM().addUser(userName, usmUser);target = new UserTarget();// 设置安全级别((UserTarget) target).setSecurityLevel(SecurityLevel.AUTH_PRIV);((UserTarget) target).setSecurityName(userName);target.setVersion(SnmpConstants.version3);} else {//设定CommunityTargettarget = new CommunityTarget();if (snmpVo.getVersion() == SnmpConstants.version1) {//设置使用的snmp版本target.setVersion(SnmpConstants.version1);} else {//设置使用的snmp版本target.setVersion(SnmpConstants.version2c);}//设置团体名((CommunityTarget) target).setCommunity(new OctetString(snmpVo.getCommunity()));}//设定地址target.setAddress(targetAddress);//设置超时重试次数target.setRetries(2);//设置超时时间target.setTimeout(TimeUnit.SECONDS.toMillis(snmpVo.getTimeout()));return target;}
这里是pdu的设置,这里面的oid非常关键,根据上面的参考文章,找到oid,随便挑一个测试就可以
/*** pdu设置* @author 汪彪* @date 2022/7/21 16:53* @param snmpVo* @param pduType* @return org.snmp4j.PDU*/private PDU setPDU(SnmpVo snmpVo,Integer pduType){PDU pdu = new PDU();for (Mib mib : snmpVo.getMib()) {pdu.add(new VariableBinding(new OID(mib.getOid())));}pdu.setType(pduType);return pdu;}
这边snmp的初始化其实也很简单,没什么需要特别注意的点
/*** snmp初始化* @author 汪彪* @date 2022/7/21 16:47* @param snmpVo* @return void*/private void initSnmp(SnmpVo snmpVo) throws IOException {snmp = new Snmp(new DefaultUdpTransportMapping());if (snmpVo.getVersion() == SnmpConstants.version3) {// 设置安全模式USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);SecurityModels.getInstance().addSecurityModel(usm);}snmp.listen();}
这边是我用来读取json文件的方法,json文件我是直接放在了resources文件夹下,大家也可以按目录去放
/*** 读取json文件* @author 汪彪* @date 2022/7/21 16:21* @param filePath* @return java.lang.String*/public static String readJson(String filePath) throws IOException {InputStream inputStream = SnmpUtil.class.getClassLoader().getResourceAsStream(filePath);File file = new File(filePath);copyInputStreamToFile(inputStream, file);if (!file.exists()) {logger.error("未找到文件");}//创建FileInputStream对象FileInputStream fileInputStream = new FileInputStream(file);//创建InputStreamReader对象InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "utf-8");//创建字符输入流BufferedReader bufferedReader = new BufferedReader(inputStreamReader);//从文件读取字符String js = "";String line = null;while ((line = bufferedReader.readLine()) != null) {js += line;}return js;}/*** 复制流* @author 汪彪* @date 2022/7/22 16:05* @param inputStream* @param file* @return void*/private static void copyInputStreamToFile(InputStream inputStream, File file) throws IOException {try (FileOutputStream outputStream = new FileOutputStream(file)) {int read;byte[] bytes = new byte[1024];while ((read = inputStream.read(bytes)) != -1) {outputStream.write(bytes, 0, read);}}}
这里是协议的配置信息,由json文件转对象时需要用到这个类
package jee.pluses.com.vo.huawei;import lombok.Data;import java.util.List;/*** Snmp协议** @author 汪彪* @date 2022/7/21*/
@Data
public class SnmpVo {/*** 品牌名称*/private String name;/*** 目标ip地址*/private String targetIp;/*** 目标端口号*/private Short targetPort;/*** 团体名*/private String community;/*** 协议版本*/private Integer version;/*** 超时设置*/private Integer timeout;/*** 用户名称*/private String userName;/****/private String userAuthPassword;/****/private String userPrivPassword;/*** 点位信息*/private List<Mib> mib;
}
这里是每个节点的信息类
package jee.pluses.com.vo.huawei;import io.swagger.annotations.ApiModelProperty;
import lombok.Data;/*** 点位信息** @author 汪彪* @date 2022/7/21*/
@Data
public class Mib {/*** 节点名称*/@ApiModelProperty(value="节点名称", name="node", dataType = "String")private String node;/*** OID*/@ApiModelProperty(value="OID", name="oid", dataType = "String")private String oid;/*** 说明*/@ApiModelProperty(value="说明", name="mean", dataType = "String")private String mean;/*** 点位值*/@ApiModelProperty(value="点位值", name="value", dataType = "String")private String value;
}
除了最下面两个类,其他方法代码都是在一个类中,以下是导包信息
import jee.pluses.com.common.PageResult;
import jee.pluses.com.service.huawei.HuaWeiService;
import jee.pluses.com.utils.PageResultUtil;
import jee.pluses.com.utils.SnmpUtil;
import jee.pluses.com.utils.huawei.HuaWeiConstants;
import jee.pluses.com.vo.huawei.Mib;
import jee.pluses.com.vo.huawei.PageModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.snmp4j.PDU;
import org.springframework.stereotype.Service;import java.io.IOException;
import java.util.List;
这是MIB Browser的参数配置,其实和上面我的配置差不多。
Address和Port在target中配置
Community也是在target中配置
Version也是在target中配置
OID则是在PDU中配置
还有右上角的请求方式,这边是由调用的时候配置,下面就是我调用的时候内容
下面是我json文件,里面的内容按照自己的需要配置改改就好
{"snmp": [{"name": "华为","targetIp": "127.0.0.1","targetPort": 161,"community": "community","version":1,"关键注释内容(无其他作用)": "version版本1为0,version版本2为1,version版本3为3","timeout": 5,"userName": "","userAuthPassword": "","userPrivPassword": "","mib": [{"node": "hwEntityCpuUsage","oid":"1.3.6.1.4.1.2011.5.25.31.1.1.1.1.5","mean": "实体CPU使用率,取值范围:2~100。"},{"node": "hwEntityMemUsage","oid":"1.3.6.1.4.1.2011.5.25.31.1.1.1.1.7","mean": "实体内存使用率,取值范围:0~100。"},{"node": "hwEntityMemSize","oid":"1.3.6.1.4.1.2011.5.25.31.1.1.1.1.9","mean": "实体内存容量,单位:Byte。"},{"node": "hwEntityTemperature","oid":"1.3.6.1.4.1.2011.5.25.31.1.1.1.1.11","mean": "实体温度,读取的是温度传感器测量温度的最高值,单位:°C。"},{"node": "hwEntityOpticalTemperature","oid":"1.3.6.1.4.1.2011.5.25.31.1.1.3.1.5","mean": "光模块温度,单位:°C。"},{"node": "hwEntityOpticalVoltage","oid":"1.3.6.1.4.1.2011.5.25.31.1.1.3.1.6","mean": "光模块电压,单位:mV。"},{"node": "hwEntityOpticalBiasCurrent","oid":"1.3.6.1.4.1.2011.5.25.31.1.1.3.1.7","mean": "光模块偏置电流,单位:uA。"},{"node": "hwEntityOpticalRxPower","oid":"1.3.6.1.4.1.2011.5.25.31.1.1.3.1.8","mean": "光模块接收功率,单位:uW,其中uW=(10^(dBM/10))*1000。\nMIB文件中定义此单位是dBm。"},{"node": "hwEntityOpticalTxPower","oid":"1.3.6.1.4.1.2011.5.25.31.1.1.3.1.9","mean": "光模块发送功率,单位:uW。\nMIB文件中定义此单位是dBm。"},{"node": "ifTable","oid":"1.3.6.1.2.1.2.2.1","mean": "接口当前接收和发送报文流量统计信息。"},{"node": "ifOperStatus","oid":"1.3.6.1.2.1.2.2.1.8","mean": "接口当前的状态。"},{"node": "hwIfMonitorInputRate","oid":"1.3.6.1.4.1.2011.5.25.41.1.7.1.1.8","mean": "入方向带宽占用率"},{"node": "hwIfMonitorOutputRate","oid":"1.3.6.1.4.1.2011.5.25.41.1.7.1.1.10","mean": "出方向带宽占用率"},{"node": "dot1dTpFdbAddress","oid":"1.3.6.1.2.1.17.4.3.1.1","mean": "获取设备上所有的MAC Address表项。"},{"node": "hwDynFdbMac","oid":"1.3.6.1.4.1.2011.5.25.42.2.1.3.1.1","mean": "用于管理设备动态MAC地址表。"},{"node": "hwArpDynTable","oid":"1.3.6.1.4.1.2011.5.25.123.1.17.1","mean": "获取设备上的动态ARP表项。"},{"node": "hwArpCfgTable","oid":"1.3.6.1.4.1.2011.5.25.123.1.18.1","mean": "用于设置和查询静态ARP表项。"},{"node": "lldpRemTable","oid":"1.0.8802.1.1.2.1.4.1.1","mean": "记录LLDP远端邻居信息。"},{"node": "dot1dStpPortState","oid":"1.3.6.1.2.1.17.2.15.1.3","mean": "标识端口当前的STP状态:\n•1:disabled\n•2:blocking\n•3:listening\n•4:learning\n•5:forwarding\n•6:broken\n"},{"node": "hwRrppRingState","oid":"1.3.6.1.4.1.2011.5.25.113.2.2.1.4","mean": "环状态。\n当前支持的取值为:\n•1: unknown\n•4: complete\n•5: failed\n•6: linkup\n•7: linkdown\n•8: preforwarding\n•9: linkupnotify\n•10: linkdownnotify\n•11: preforwardnotify\n"},{"node": "vrrpOperState","oid":"1.3.6.1.2.1.68.1.3.1.3","mean": "虚拟路由器的当前状态。此对象定义了四个值:\n•initialize(1):初始化状态。在此状态下,设备不会对VRRP报文做任何处理。\n•backup(2):备用状态。在此状态下,设备接收Master设备发送的VRRP报文,判断Master设备工作是否正常。\n•master(3):主用状态。在此状态下,设备定期发送VRRP通告报文,并转发目的MAC地址是虚拟MAC地址的IP报文。"}]}]
}
突然发现忘记加导包的内容了
这个是gradle的导入
//snmpimplementation 'org.snmp4j:snmp4j:2.8.3'
这个是pom的导入
//snmp
<dependency><groupId>org.snmp4j</groupId><artifactId>snmp4j</artifactId><version>2.8.3</version>
</dependency>
java snmp协议 获取数据相关推荐
- java 通过snmp协议获取物理机CPU、内存容量及使用率,存储的容量及使用率
java 用snmp协议获取物理机CPU.内存容量及使用率,存储的容量及使用率,java获取trap告警 一.SNMP简介 1.什么是snmp 二.SNMP获取信息步骤 1.开启SNMP 2.MIB文 ...
- androidclient和站点数据交互的实现(基于Http协议获取数据方法)
androidclient一般不直接訪问站点数据库,而是像浏览器一样发送get或者post请求.然后站点返回client能理解的数据格式,client解析这些数据.显示在界面上.经常使用的数据格式是x ...
- windows系统下SNMP协议获取系统内存、CPU实例代码
系统环境:win10 注:win10及以下windows平台,在控制面板,程序中,添加snmp服务功能. 可参照:https://jingyan.baidu.com/article/3d69c5515 ...
- Java使用JDBC获取数据并打印出来
JDBC代表Java数据库连接,这对Java编程语言和广泛的数据库之间独立于数据库的连接标准的Java API. JDBC API提供了以下接口和类: Tables Cool DriverManage ...
- python读取网络端口数据_在Python中从SNMP端口获取数据
我专门尝试使用PySNMP库从python中的SNMP端口读取数据.我有兴趣仅通过此库获取数据.这是因为我正在从NetSNMP迁移到PySNMP. 这是我为NetSNMP编写的工作代码,它实际上为我提 ...
- java从键盘获取数据_java实现从键盘获取数据的方法
java实现从键盘获取数据的方法 发布时间:2020-06-25 15:42:06 来源:亿速云 阅读:83 作者:Leah 这期内容当中小编将会给大家带来有关java实现从键盘获取数据的方法,文章内 ...
- java tbase_使用Java从firebase获取数据
我在下面的代码中遇到了一个问题,该代码几乎逐字地从Firebase SDK Java文档中复制到了工作中.我是一个真正的语言的新手,比如来自PHP和JavaScript的webdev背景的Java. ...
- java通过扫码枪获取数据
1.通过按钮获取输入框焦点 2.扫描二维码或条形码,并设置回车键(大部分扫描枪已自动设置) 3.在输入框设置回车 事件 4.获取输入框的值,将数据传入数据库 <script type=" ...
- Python:通过SNMP协议获取H3C、华为交换机的VLAN信息及ARP地址表
我测试是H3C S3600交换机和华为S3700交换机 交换机SNMP配置 system-view 进入交换机的配置模式 配置community 只读属性为public,且配置版本为所有 #[swit ...
最新文章
- Homebrew安装(MacOS)
- 克隆真人语音只要1句话,AI问诊超96.4%全科医生!科大讯飞年度黑科技大秀,余承东都来了...
- 根据id/类名/元素名称查找元素
- linux 单个网卡配置多个IP
- 再谈poj2965(高效算法)
- 前端开发学习笔记(一)深入浅出Javascript
- 7-4 哈利·波特的考试 (25 分)(C语言实现)
- dede搜索正文内容search.php,织梦dede后台怎么查找文章内容关键词
- 使用tornado让你的请求异步非阻塞
- Pspice 使用指南(中文)
- Win10 PSCAD4.5安装心路历程Mark
- 【加拿大签证】加拿大工签/工作许可work permit 办理流程【官方详细完整,加拿大访问学者必看】
- gitbub 上删除仓库
- Gimp去除图片背景色方法
- 计算机屏幕截图按什么键,电脑上截图按哪个键_电脑截图快捷键是什么
- DevOps落地实践:普元:PRIMETON DEVOPS
- 计算机二级讲座宣传语,计算机二级讲座策划书.doc
- Java面试题上篇(转)
- web服务器、数据库服务器
- Python文本分析案例:近体诗格律分析