Java發(fā)送SNMP至交換機獲取交換機狀態(tài)實現(xiàn)方式
交換機協(xié)議
這里使用的交換機協(xié)議為常見的RCF1213-MIB協(xié)議,使用SNMP協(xié)議與交換機進行通信。前提記得開啟交換機對于SNMP協(xié)議的支持
SNMP庫
使用SNMP4J庫進行開發(fā),maven提供了相應(yīng)的pom,筆者使用的版本為2.7.0。pom內(nèi)容如下
<!-- snmp4j依賴包 -->
<dependency>
<groupId>org.snmp4j</groupId>
<artifactId>snmp4j</artifactId>
<version>2.7.0</version>
</dependency>
獲取交換機單路狀態(tài)
首先明確交換機所在的IP地址,交換機提供的公共團體名稱以及對應(yīng)的OID
團體名稱簡單的來說就是驗證碼
如果 A 要訪問B 的核心內(nèi)容A 必須有B 的公鑰,在和B 通信的時候B 也必須能認證A 持有的公鑰
這個過程中的公鑰和SNMP的團體名稱功能類似
- OID(對象標(biāo)識符),是SNMP代理提供的具有唯一標(biāo)識的鍵值。
- OID看起來和一個IPv6的地址很像,并且不同的廠商有不同的前綴等信息。具體可以在協(xié)議文件中查看。公開的協(xié)議OID也可在網(wǎng)絡(luò)上查詢到。
// 配置交換機的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";
第二步設(shè)定好目標(biāo)地址以及基礎(chǔ)的超時重試信息
其中SNMP協(xié)議一共有三個版本,第一代能力欠缺,第三代還處于測試階段,因此使用能力較為豐富且穩(wěn)定的第二代SNMP協(xié)議。
- SNMPv1: SNMPv1是最早的SNMP版本,它提供最基本的網(wǎng)絡(luò)管理功能。它使用簡單的社區(qū)字符串(community string)來進行認證,發(fā)送的消息以明文形式傳輸。SNMPv1具有較少的安全功能,并且易受到攻擊。
- SNMPv2: SNMPv2是對SNMPv1的改進版本。它引入了擴展的管理功能和更復(fù)雜的消息格式。SNMPv2分為SNMPv2c(community-basedSNMPv2)和SNMPv2u(user-basedSNMPv2)兩種形式。SNMPv2c仍然使用社區(qū)字符串進行認證,而SNMPv2u引入了更復(fù)雜的用戶認證和訪問控制機制。然而,SNMPv2的安全性仍然有限,容易受到攻擊。
- SNMPv3: SNMPv3是最新和最安全的SNMP版本。它提供了更強大的安全性功能,如消息加密、用戶身份認證和訪問控制。SNMPv3使用基于用戶的安全模型(USM)來提供安全性。用戶可以使用用戶名和密碼進行身份認證,并且可以使用加密機制對消息進行保護。SNMPv3還引入了VACM(View-based Access Control Model)來管理對設(shè)備的訪問控制。
// 創(chuàng)建目標(biāo)地址。這里使用的是UDP協(xié)議,并指定了交換機的IP地址和SNMP端口161。
Address targetAddress = GenericAddress.parse("udp:" + ipAddress + "/161");
// 創(chuàng)建一個社區(qū)目標(biāo)對象,用于存儲SNMP的目標(biāo)信息。
CommunityTarget target = new CommunityTarget();
// 設(shè)置目標(biāo)的社區(qū)字符串。這里使用的是"public"。
target.setCommunity(new OctetString(community));
// 設(shè)置目標(biāo)的地址,即前面創(chuàng)建的目標(biāo)地址。
target.setAddress(targetAddress);
// 設(shè)置請求失敗時的重試次數(shù),這里設(shè)置為2次。
target.setRetries(2);
// 設(shè)置請求的超時時間,單位為毫秒,這里設(shè)置為1500毫秒(1.5秒)。
target.setTimeout(1500);
// 設(shè)置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)));
// 設(shè)置PDU的類型為GETNEXT,用于獲取單個變量。
pdu.setType(PDU.GETNEXT);
// 發(fā)送請求
boolean finished = false;
while (!finished) {
// 發(fā)送SNMP請求,并接收響應(yīng)事件。
ResponseEvent responseEvent = snmp.send(pdu, target);
// 獲取響應(yīng)PDU。
PDU responsePDU = responseEvent.getResponse();
.............
.............
}
snmp.close();
// 關(guān)閉SNMP對象,釋放資源。
} catch (Exception e) {
e.printStackTrace();
// 捕獲并打印異常。
}
第四步處理我們請求的返回值
if (responsePDU != null) {
for (VariableBinding vb : responsePDU.getVariableBindings()) {
// 檢查響應(yīng)中的OID是否屬于請求的OID范圍。
if (vb.getOid().toString().startsWith(oidValue)) {
// 打印OID及其對應(yīng)的變量值。
System.out.println(vb.getOid() + " = " + vb.getVariable());
// 重置請求ID。
pdu.setRequestID(new Integer32(0));
// 將PDU的第一個變量設(shè)置為上次收到的OID,以獲取下一個變量。
pdu.set(0, vb);
} else {
// 如果OID不再屬于請求的范圍,則完成循環(huán)。
finished = true;
break;
}
}
} else {
finished = true;
// 如果響應(yīng)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)建目標(biāo)
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("響應(yīng)PDU為空");
}
snmp.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
獲取交換機多路狀態(tài)
關(guān)鍵點就在于修改PDU的屬性設(shè)置,其他同單路一樣。
SNMP的GETBULK操作來獲取多個結(jié)果,可以提高獲取大量信息的效率。
pdu.setType(PDU.GETBULK); // 每次請求的最大重復(fù)次數(shù) pdu.setMaxRepetitions(10); // 非重復(fù)計數(shù)器 pdu.setNonRepeaters(0);
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
如何使用spring gateway微服務(wù)網(wǎng)關(guān)(基本用法)
本文介紹spring gateway的使用,包括配置文件的使用和調(diào)試跟蹤,讓大家了解spring gateway的基本用法,感興趣的朋友跟隨小編一起看看吧2024-08-08
SpringBoot讀取yml文件中配置數(shù)組的2種方法
這篇文章主要介紹了SpringBoot讀取yml文件中配置數(shù)組的2種方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
java求最大公約數(shù)與最小公倍數(shù)的方法示例
這篇文章主要介紹了java求最大公約數(shù)與最小公倍數(shù)的方法,涉及java數(shù)值運算的相關(guān)操作技巧,并附帶分析了eclipse環(huán)境下設(shè)置運行輸入?yún)?shù)的相關(guān)操作技巧,需要的朋友可以參考下2017-11-11
詳解eclipse將項目打包成jar文件的兩種方法及問題解決方法
本文給大家介紹了eclipse中將項目打包成jar文件的兩種方法及其遇到問題解決方法,本文圖文并茂給大家介紹的非常詳細,需要的朋友可以參考下2017-12-12

