一、Windows开启SNMP服务
这里以Windows11为例:
1、安装SNMP服务
(1)通过win+x快捷键打开电脑“设置”,然后在“应用”中选择”可选功能“。
(2)点击”可选功能“的”查看功能“
(3)找到并勾选“WMI SNMP 供应商",再点击”下一步“。这里借用下百度的图,因为本人已经安装好。
(4)安装”WMI SNMP 供应商",再点击“安装”,最后等待安装完成即可。
(5)安装完之后即可看到。
至此,SNMP已经安装完毕。接下来就是做一些基础配置,这样才能真正的通过Java代码获取到设备的信息。
2、配置SNMP服务
(1)打开服务,找到SNMP。
(2)双击SNMP服务,选择“安全”。然后配置社区名称和接收哪些主机的SNMP报文,如下图所示。
至此,SNMP的配置彻底完成。接下来要做的就是通过代码获取设备信息。
二、代码实现
(1)引入SNMP4J的jar包
如果是Maven工程,直接引入依赖。
<dependency>
<groupId>org.snmp4j</groupId>
<artifactId>snmp4j</artifactId>
<version>2.8.3</version>
</dependency>
如果是在IDEA的lib目录下引入jar包,则先将下载的jar包放入lib目录下,然后选中jar包,右键选择Add as Library即可。
这里给出maven的网址:https://mvnrepository.com/
对于一些jar包的下载,也可以通过该网址去下载。
(2)代码实现
只要和其他电脑在同一个局域网,并且其他电脑开启了SNMP服务,那么就可以通过更改IP地址,实现对与之相连的局域网内的所有主机的信息的获取。而通过更改不同的OID,就可以实现对主机的其他信息的获取。
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.*;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import java.io.IOException;
/**
* 获取设备信息
*
* @author zengLingYao
* @date 2021/12/02
*/
public class Test {
/**
* 获取系统基本信息
*/
public final static String SYS_DESC = "1.3.6.1.2.1.1.1";
/**
* 获取机器名
*/
public final static String SYS_NAME = "1.3.6.1.2.1.1.5";
/**
* 监控时间
*/
public final static String SYS_UPTIME = "1.3.6.1.2.1.1.3";
public static void main(String[] args) {
try {
System.out.println("基本信息:"+getMessageByIpAndOid("192.168.1.111",SYS_DESC));
System.out.println("获取机器名:"+getMessageByIpAndOid("192.168.1.111",SYS_NAME));
System.out.println("监控时间:"+getMessageByIpAndOid("192.168.1.111",SYS_UPTIME));
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getMessageByIpAndOid(String ip, String oid) throws Exception{
String variableString = "";
try{
//设定CommunityTarget
CommunityTarget myTarget = new CommunityTarget();
//机器的地址
Address address = GenericAddress.parse("udp:"+ip+"/161");
//设定地址
myTarget.setAddress(address);
//设置snmp共同体
myTarget.setCommunity(new OctetString("public"));
//设置超时重试次数
myTarget.setRetries(2);
//设置超时的时间
myTarget.setTimeout(5*60);
//设置使用的snmp版本
myTarget.setVersion(SnmpConstants.version2c);
//设定采取的协议
TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
//调用TransportMapping中的listen()方法,启动监听进程,接收消息,由于该监听进程是守护进程,最后应调用close()方法来释放该进程
transport.listen();
//创建SNMP对象,用于发送请求PDU
Snmp protocol = new Snmp(transport);
//创建请求pdu,获取mib
PDU request = new PDU();
//调用的add方法绑定要查询的OID
request.add(new VariableBinding(new OID(oid)));
//调用setType()方法来确定该pdu的类型
request.setType(PDU.GETNEXT);
//调用 send(PDU pdu,Target target)发送pdu,返回一个ResponseEvent对象
ResponseEvent responseEvent = protocol.send(request, myTarget);
//通过ResponseEvent对象来获得SNMP请求的应答pdu,方法:public PDU getResponse()
PDU response=responseEvent.getResponse();
//输出
if(response != null){
//通过应答pdu获得mib信息(之前绑定的OID的值),方法:VaribleBinding get(int index)
VariableBinding vb = response.get(0);
System.out.println(vb);
variableString = String.valueOf(vb.getVariable());
//调用close()方法释放该进程
transport.close();
}
}catch(IOException e){
e.printStackTrace();
}
return variableString;
}
}
执行结果如下:
以上就是整个的配置和代码获取的过程。还有一个注意点就是:如果是局域网内的设备信息采集,需要将管理站的信息配置在SNMP服务的IP地址列表中,如下图:
管理站即运行代码的电脑的IP地址是:192.168.1.101,而被管理站的IP地址是192.168.1.111.因此在被管理站的SNMP服务中配置了管理站的IP地址。
也可以直接将被管理站的SNMP服务直接设置为“接受来自任何主机的SNMP数据包”,如下图: