当前位置: 代码网 > it编程>编程语言>Java > Java发送SNMP至交换机获取交换机状态实现方式

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

2025年09月26日 Java 我要评论
交换机协议这里使用的交换机协议为常见的rcf1213-mib协议,使用snmp协议与交换机进行通信。前提记得开启交换机对于snmp协议的支持snmp库使用snmp4j库进行开发,maven提供了相应的

交换机协议

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

snmp库

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

    <!-- snmp4j依赖包 -->
    <dependency>
        <groupid>org.snmp4j</groupid>
        <artifactid>snmp4j</artifactid>
        <version>2.7.0</version>
    </dependency>

获取交换机单路状态

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

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

如果 a 要访问b 的核心内容a 必须有b 的公钥,在和b 通信的时候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.println(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.snmp4j.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);

            // 发送请求
            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);

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com