Java發(fā)送SNMP至交換機獲取交換機狀態(tài)實現(xiàn)方式
交換機協(xié)議
這里使用的交換機協(xié)議為常見的RCF1213-MIB協(xié)議,使用SNMP協(xié)議與交換機進行通信。前提記得開啟交換機對于SNMP協(xié)議的支持
SNMP庫
使用SNMP4J庫進行開發(fā),maven提供了相應的pom,筆者使用的版本為2.7.0。pom內容如下
<!-- snmp4j依賴包 -->
<dependency>
<groupId>org.snmp4j</groupId>
<artifactId>snmp4j</artifactId>
<version>2.7.0</version>
</dependency>
獲取交換機單路狀態(tài)
首先明確交換機所在的IP地址,交換機提供的公共團體名稱以及對應的OID
團體名稱簡單的來說就是驗證碼
如果 A 要訪問B 的核心內容A 必須有B 的公鑰,在和B 通信的時候B 也必須能認證A 持有的公鑰
這個過程中的公鑰和SNMP的團體名稱功能類似
- OID(對象標識符),是SNMP代理提供的具有唯一標識的鍵值。
- OID看起來和一個IPv6的地址很像,并且不同的廠商有不同的前綴等信息。具體可以在協(xié)議文件中查看。公開的協(xié)議OID也可在網(wǎng)絡上查詢到。
// 配置交換機的SNMP參數(shù)
// 交換機的IP地址
String ipAddress = "192.168.1.1";
// 公共團體名稱
String community = "public";
// RFC1213-MIB中的ifOperStatus OID,用于獲取接口的操作狀態(tài)
String oidValue = "1.3.6.1.2.1.2.2.1.8";
第二步設定好目標地址以及基礎的超時重試信息
其中SNMP協(xié)議一共有三個版本,第一代能力欠缺,第三代還處于測試階段,因此使用能力較為豐富且穩(wěn)定的第二代SNMP協(xié)議。
- SNMPv1: SNMPv1是最早的SNMP版本,它提供最基本的網(wǎng)絡管理功能。它使用簡單的社區(qū)字符串(community string)來進行認證,發(fā)送的消息以明文形式傳輸。SNMPv1具有較少的安全功能,并且易受到攻擊。
- SNMPv2: SNMPv2是對SNMPv1的改進版本。它引入了擴展的管理功能和更復雜的消息格式。SNMPv2分為SNMPv2c(community-basedSNMPv2)和SNMPv2u(user-basedSNMPv2)兩種形式。SNMPv2c仍然使用社區(qū)字符串進行認證,而SNMPv2u引入了更復雜的用戶認證和訪問控制機制。然而,SNMPv2的安全性仍然有限,容易受到攻擊。
- SNMPv3: SNMPv3是最新和最安全的SNMP版本。它提供了更強大的安全性功能,如消息加密、用戶身份認證和訪問控制。SNMPv3使用基于用戶的安全模型(USM)來提供安全性。用戶可以使用用戶名和密碼進行身份認證,并且可以使用加密機制對消息進行保護。SNMPv3還引入了VACM(View-based Access Control Model)來管理對設備的訪問控制。
// 創(chuàng)建目標地址。這里使用的是UDP協(xié)議,并指定了交換機的IP地址和SNMP端口161。
Address targetAddress = GenericAddress.parse("udp:" + ipAddress + "/161");
// 創(chuàng)建一個社區(qū)目標對象,用于存儲SNMP的目標信息。
CommunityTarget target = new CommunityTarget();
// 設置目標的社區(qū)字符串。這里使用的是"public"。
target.setCommunity(new OctetString(community));
// 設置目標的地址,即前面創(chuàng)建的目標地址。
target.setAddress(targetAddress);
// 設置請求失敗時的重試次數(shù),這里設置為2次。
target.setRetries(2);
// 設置請求的超時時間,單位為毫秒,這里設置為1500毫秒(1.5秒)。
target.setTimeout(1500);
// 設置SNMP的版本,這里使用的是SNMP v2c。
target.setVersion(SnmpConstants.version2c);
第三步創(chuàng)建TransportMapping并監(jiān)聽SNMP的返回值
第三步主要通過PDU這個對象單元來進行數(shù)據(jù)的交換。
一個PDU(Protocol Data Unit)對象,用于封裝SNMP請求。
try {
// 創(chuàng)建UDP傳輸映射,用于SNMP通信。
TransportMapping<?> transport = new DefaultUdpTransportMapping();
// 監(jiān)聽傳輸映射,即啟動SNMP傳輸。
transport.listen();
// 創(chuàng)建一個Snmp對象,用于發(fā)送和接收SNMP消息
Snmp snmp = new Snmp(transport);
// 創(chuàng)建PDU
PDU pdu = new PDU();
// 創(chuàng)建一個PDU(Protocol Data Unit)對象,用于封裝SNMP請求。
pdu.add(new VariableBinding(new OID(oidValue)));
// 設置PDU的類型為GETNEXT,用于獲取單個變量。
pdu.setType(PDU.GETNEXT);
// 發(fā)送請求
boolean finished = false;
while (!finished) {
// 發(fā)送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不再屬于請求的范圍,則完成循環(huán)。
finished = true;
break;
}
}
} else {
finished = true;
// 如果響應PDU為空,則完成循環(huán)。
}
完整代碼如下
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參數(shù)
// 交換機的IP地址
String ipAddress = "192.168.1.1";
// 公共團體名稱
String community = "public";
// RFC1213-MIB中的ifOperStatus OID,用于獲取接口的操作狀態(tài)
String oidValue = "1.3.6.1.2.1.2.2.1.8";
// 創(chuàng)建目標
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);
// 創(chuàng)建TransportMapping并監(jiān)聽
try {
TransportMapping<?> transport = new DefaultUdpTransportMapping();
transport.listen();
Snmp snmp = new Snmp(transport);
// 創(chuàng)建PDU
PDU pdu = new PDU();
pdu.add(new VariableBinding(new OID(oidValue)));
pdu.setType(PDU.GETNEXT);
// 發(fā)送請求
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();
}
}
}
獲取交換機多路狀態(tài)
關鍵點就在于修改PDU的屬性設置,其他同單路一樣。
SNMP的GETBULK操作來獲取多個結果,可以提高獲取大量信息的效率。
pdu.setType(PDU.GETBULK); // 每次請求的最大重復次數(shù) pdu.setMaxRepetitions(10); // 非重復計數(shù)器 pdu.setNonRepeaters(0);
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Java-Redis-Redisson分布式鎖的功能使用及實現(xiàn)
這篇文章主要介紹了Java-Redis-Redisson-分布式鎖的功能使用及實現(xiàn),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08
SpringMVC開發(fā)中十大常見問題深度解析與解決方案
在Java Web開發(fā)領域,SpringMVC作為一款主流的Web框架,憑借其強大的功能和便捷的開發(fā)體驗深受開發(fā)者喜愛,然而,在實際使用過程中,開發(fā)者常常會遇到各種各樣的“坑”,本文將針對SpringMVC開發(fā)中常見的十大問題,需要的朋友可以參考下2025-06-06
SpringBoot中的@ControllerAdvice使用方法詳細解析
這篇文章主要介紹了SpringBoot中的@ControllerAdvice使用方法詳細解析, 加了@ControllerAdvice的類為那些聲明了@ExceptionHandler、@InitBinder或@ModelAttribute注解修飾的 方法的類而提供的專業(yè)化的@Component,以供多個 Controller類所共享,需要的朋友可以參考下2024-01-01
java中的HashSet與 == 和 equals的區(qū)別示例解析
HashSet是Java中基于哈希表實現(xiàn)的集合類,特點包括:元素唯一、無序和可包含null,本文給大家介紹java中的HashSet與 == 和 equals的區(qū)別,感興趣的朋友一起看看吧2025-02-02
SpringBoot實現(xiàn)多數(shù)據(jù)源的實戰(zhàn)案例
這篇文章主要介紹了SpringBoot實現(xiàn)多數(shù)據(jù)源的實戰(zhàn)案例,文中通過示例代碼和圖文展示介紹的非常詳細,對大家的學習或工作有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2024-01-01

