Java发送SNMP至交换机获取交换机状态实现方式

2025-09-27 01:50

本文主要是介绍Java发送SNMP至交换机获取交换机状态实现方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Java发送SNMP至交换机获取交换机状态实现方式》文章介绍使用SNMP4J库(2.7.0)通过RCF1213-MIB协议获取交换机单/多路状态,需开启SNMP支持,重点对比SNMPv1、v2c、v...

交换机协议

这里使用的交换机协议为常见的RCF1213-MIB协议,使用SNMP协议与交换机进行通信。前提记得开启交换机对于SNMP协议的支持

SNMP库

使用SNMP4J库进行开发,maven提供了相应的pom,笔者使用的版本为2.7.0。pom内容如下

    <!-- snmp4j依赖包 -->
    <dependency>
        <groandroidupId>org.snmp4j</groupId>
        <artifactId>snmp4j</artifactId>
        <version>2.7.0</version>
    </dependency>

获取交换机单路状态

首先明确交换机所在的IP地址,交换机提供的公共团体名称以及对应的OID

团体名称简单的来说就是验证码

如果 A 要访问B 的核心内容A 必须有B 的公钥,在和B 通信的时http://www.chinasem.cn候B 也必须能认证A 持有的公钥

这个过程中的公钥和SNMP的团体名称功能类似

  • OID(对象标识符),是SNMP代理提供的具有唯一标识的键值。
  • OID看起来和一个IPv6的地址很像,并且不同的厂商有不同的前缀等信息。具体可以在协议文件中查看。公开的协议OID也可在网络上查询到。
		// 配置交换机的SNMP参数
		// 交换机的IP地址
        String ipAddress = "192.168.1.1";
        // 公共团体名称
        String community = "public";
        // RFC1213-MIB中的ifOperStatus OID,用于获取接口的操作状态
        String oidValue = "1.3.6.1.2.1.2.2.1.8";

第二步设定好目标地址以及基础的超时重试信息

其中SNMP协议一共有三个版本,第一代能力欠缺,第三代还处于测试阶段,因此使用能力较为丰富且稳定的第二代SNMP协议。

  • SNMPv1: SNMPv1是最早的SNMP版本,它提供最基本的网络管理功能。它使用简单的社区字符串(community string)来进行认证,发送的消息以明文形式传输。SNMPv1具有较少的安全功能,并且易受到攻击。
  • SNMPv2: SNMPv2是对SNMPv1的改进版本。它引入了扩展的管理功能和更复杂的消息格式。SNMPv2分为SNMPv2c(community-basedSNMPv2)和SNMPv2u(user-basedSNMPv2)两种形式。SNMPv2c仍然使用社区字符串进行认证,而SNMPv2u引入了更复杂的用户认证和访问控制机制。然而,SNMPv2的安全性仍然有限,容易受到攻击。
  • SNMPv3: SNMPv3是最新和最安全的SNMP版本。它提供了更强大的安全性功能,如消息加密、用户身份认证和访问控制。SNMPv3使用基于用户的安全模型(USM)来提供安全性。用户可以使用用户名和密码进行身份认证,并且可以使用加密机制对消息进行保护。SNMPv3还引入了VACM(View-based Access Control Model)来管理对设备的访问控制。
		// 创建目标地址。这里使用的是UDP协议,并指定了交换机的IP地址和SNMP端口161。
        Address targetAddress = GenericAddress.parse("udp:" + ipAddress + "/161");
        // 创建一个社区目标对象,用于存储SNMP的目标信息。        
        CommunityTarget target = new CommunityTarget();
        // 设置目标的社区字符串。这里使用的是"public"。
        target.setCommunity(new OctetString(community));
        // 设置目标的地址,即前面创建的目标地址。
        target.setAddress(targetAddress);
        // 设置请求失败时的重试次数,这里设置为2次。
        target.setRetries(2);
        // 设置请求的超时时间,单位为毫秒,这里设置为1500毫秒(1.5秒)。
        target.setTimeout(1500);
        // 设置SNMP的版本,这里使用的是SNMP v2c。
        target.setVersion(SnmpConstants.version2c);

第三步创建TransportMapping并监听SNMP的返回值

第三步主要通过PDU这个对象单元来进行数据的交换。

一个PDU(Protocol Data Unit)对象,用于封装SNMP请求。

		try {
			// 创建UDP传输映射,用于SNMP通信。
            TransportMapping<?> transport = new DefaultUdpTransportMapping();
            // 监听传输映射,即启动SNMP传输。
            transport.listen();
			// 创建一个Snmp对象,用于发送和接收SNMP消息
            Snmp snmp = new Snmp(transport);
            // 创建PDU
            PDU pdu = new PDU();
            // 创建一个PDU(Protocol Data Unit)对象,用于封装SNMP请求。
            pdu.add(new VariableBinding(new OID(oidValue)));
             // 设置PDU的类型为GETNEXT,用于获取单个变量。
            pdu.setType(PDU.GETNEXT);     
            // 发送请求
            boolean finished = false;
            while (!finished) {
            	// 发送SNMP请求,并接收响应事件。
                ResponseEvent responseEvent = snmp.send(pdu, target);
                 // 获取响应PDU。
                PDU responsePDU = responseEvent.getResponse();
                .............
            	.............  
            }
            snmp.close();
            // 关闭SNMP对象,释放资源。
        } catch (Exception e) {
            e.printStackTrace();
            // 捕获并打印异常。
        }

第四步处理我们请求的返回值

if (responsePDU != null) {
    for (VariableBinding vb : responsePDU.getVariableBindings()) {
    	// 检查响应中的OID是否属于请求的OID范围。
        if (vb.getOid().toString().startsWith(oidValue)) {
             // 打印OID及其对应的变量值。
            System.out.androidprintln(vb.getOid() + " = " + vb.getVariable());
            // 重置请求ID。
            pdu.setRequestID(new Integer32(0));
          // 将PDU的第一个变量设置为上次收到的OID,以获取下一个变量。
            pdu.set(0, vb);  
        } else {
         	// 如果OID不再属于请求的范围,则完成循环。
            finished = true;
            break;
        }
    }
} else {
    finished = true;
    // 如果响应PDU为空,则完成循环。
}

完整代码如下

import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snphpmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
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;

public class SnmpGet {

    public static void main(String[] args) {
        // 配置交换机的SNMP参数
         // 交换机的IP地址
        String ipAddress = "192.168.1.1";
         // 公共团体名称
        String community = "public";
        // RFC1213-MIB中的ifOperStatus OID,用于获取接口的操作状态
        String oidValue = "1.3.6.1.2.1.2.2.1.8"; 

        // 创建目标
        Address targetAddress = GenericAddress.parse("udp:" + ipAddress + "/161");
        CommunityTarget target = new CommunityTarget();
        target.setCommunity(new OctetString(community));
        target.setAddress(targetAddress);
        target.setRetries(2);
        target.setTimeout(1500);
        target.setVersion(SnmpConstants.version2c);

        // 创建TransportMapping并监听
        try {
            TransportMapping<?> transport = new DefaultUdpTransportMapping();
            transport.listen();
            Snmp snmp = new Snmp(transport);

            // 创建PDU
            PDU pdu = new PDU();
            pdu.add(new VariableBinding(new OID(oidValue)));
            pdu.setType(PDU.GETNEXT);

            //eEYXpahd 发送请求
            ResponseEvent responseEvent = snmp.send(pdu, target);
            PDU responsePDU = responseEvent.getResponse();

            if (responsePDU != null) {
                for (VariableBinding vb : responsePDU.getVariableBindings()) {
                    System.out.println(vb.getOid() + " = " + vb.getVariable());
                }
            } else {
                System.out.println("响应PDU为空");
            }

            snmp.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

获取交换机多路状态

关键点就在于修改PDU的属性设置,其他同单路一样。

SNMP的GETBULK操作来获取多个结果,可以提高获取大量信息的效率。

pdu.setType(PDU.GETBULK);
 // 每次请求的最大重复次数
pdu.setMaxRepetitions(10);
 // 非重复计数器
pdu.setNonRepeaters(0);

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持China编程(www.chinasem.cn)。

这篇关于Java发送SNMP至交换机获取交换机状态实现方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1156056

相关文章

Go语言中json操作的实现

《Go语言中json操作的实现》本文主要介绍了Go语言中的json操作的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录 一、jsOChina编程N 与 Go 类型对应关系️ 二、基本操作:编码与解码 三、结构体标签(Struc

Spring的基础事务注解@Transactional作用解读

《Spring的基础事务注解@Transactional作用解读》文章介绍了Spring框架中的事务管理,核心注解@Transactional用于声明事务,支持传播机制、隔离级别等配置,结合@Tran... 目录一、事务管理基础1.1 Spring事务的核心注解1.2 注解属性详解1.3 实现原理二、事务事

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

docker 重命名镜像的实现方法

《docker重命名镜像的实现方法》在Docker中无法直接重命名镜像,但可通过添加新标签、删除旧镜像后重新拉取/构建,或在DockerCompose中修改配置文件实现名称变更,感兴趣的可以了解一下... 目录使用标签(Tagging)删除旧的php镜像并重新拉取或构建使用docker Compose在Do

Vue实现路由守卫的示例代码

《Vue实现路由守卫的示例代码》Vue路由守卫是控制页面导航的钩子函数,主要用于鉴权、数据预加载等场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、概念二、类型三、实战一、概念路由守卫(Navigation Guards)本质上就是 在路

k8s admin用户生成token方式

《k8sadmin用户生成token方式》用户使用Kubernetes1.28创建admin命名空间并部署,通过ClusterRoleBinding为jenkins用户授权集群级权限,生成并获取其t... 目录k8s admin用户生成token创建一个admin的命名空间查看k8s namespace 的

C#自动化实现检测并删除PDF文件中的空白页面

《C#自动化实现检测并删除PDF文件中的空白页面》PDF文档在日常工作和生活中扮演着重要的角色,本文将深入探讨如何使用C#编程语言,结合强大的PDF处理库,自动化地检测并删除PDF文件中的空白页面,感... 目录理解PDF空白页的定义与挑战引入Spire.PDF for .NET库核心实现:检测并删除空白页

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

Java JUC并发集合详解之线程安全容器完全攻略

《JavaJUC并发集合详解之线程安全容器完全攻略》Java通过java.util.concurrent(JUC)包提供了一整套线程安全的并发容器,它们不仅是简单的同步包装,更是基于精妙并发算法构建... 目录一、为什么需要JUC并发集合?二、核心并发集合分类与详解三、选型指南:如何选择合适的并发容器?在多