环境:java+gradle+snmp4j
编译器idea
进入正题
首先,我们编写一个snmp接收类
package main.snmp.util;
import org.snmp4j.*;
import org.snmp4j.mp.StateReference;
import org.snmp4j.mp.StatusInformation;
import org.snmp4j.smi.TcpAddress;
import org.snmp4j.transport.DefaultTcpTransportMapping;
/**
* snmp trap和inform接收类
*/
public class InformReceiver implements CommandResponder {
private int port;
private Snmp snmp;
public InformReceiver(int port){
this.port = port;
}
/**
* 完成初始化并启动监听
*/
public void startListener() {
try {
TransportMapping transport = new DefaultTcpTransportMapping(
new TcpAddress(port));
snmp = new Snmp(transport);
snmp.addCommandResponder(this);
snmp.listen();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 处理接收到的消息
*/
@Override
public void processPdu(CommandResponderEvent event) {
System.out.print("receive Message :");
PDU pdu = event.getPDU();
System.out.println(pdu);
if(pdu.getType()==PDU.INFORM) {
//如果是Inform消息,需要回应,如果不回应,那么客户端就会重复inform消息
pdu.setErrorIndex(0);
pdu.setErrorStatus(0);
pdu.setType(PDU.RESPONSE);
StatusInformation statusInformation = new StatusInformation();
StateReference ref = event.getStateReference();
try {
event.getMessageDispatcher().returnResponsePdu(
event.getMessageProcessingModel(),
event.getSecurityModel(), event.getSecurityName(),
event.getSecurityLevel(), pdu,
event.getMaxSizeResponsePDU(), ref, statusInformation);
} catch (MessageException ex) {
ex.printStackTrace();
}
}
}
}
接着,我们再编写一个snmp发送类
package main.snmp.util;
import org.snmp4j.*;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.*;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* snmp发送类,发送trap和inform
*/
public class InformSender {
private Snmp snmp;
public void Connect() throws IOException {
TransportMapping<?> mapping = new DefaultTcpTransportMapping();
snmp = new Snmp(mapping);
}
/**
* 获取时间参数
* @param currentTime
* @return
*/
private static Variable getSysUpTimeVariable(long currentTime){
TimeTicks result = new TimeTicks(0);
long i = 0L;
if(i == 0L || currentTime == 0L){
}else{
result.setValue((currentTime - i)/10);
}
return result;
}
/**
* 获取目标地址
* @param address
* @param community
* @return
*/
public static Target getTargetV2(final String address, final String community){
Address targetAddress = GenericAddress.parse(address);
String str = community==null?"":community;
Target target = new CommunityTarget(targetAddress, new OctetString(str));
target.setAddress(targetAddress);
target.setRetries(3); //当发送trap的时候不生效,发送Inform的时候会生效
target.setTimeout(1 * 1000);//等待回应时间
target.setVersion(SnmpConstants.version2c);
return target;
}
/**
* 构造一个参数列表,用来测试发送数据
*/
private List<VariableBinding> getVariable(){
List<VariableBinding> variables = new ArrayList<>();
VariableBinding upTimeVB = new VariableBinding();
upTimeVB.setOid(SnmpConstants.sysUpTime);
Variable upTimeVar = getSysUpTimeVariable(System.currentTimeMillis());
upTimeVB.setVariable(upTimeVar);
variables.add(upTimeVB);
return variables;
}
public boolean sendInform(Target target) throws IOException {
List<VariableBinding> variables = getVariable();
return sendInform(target, variables);
}
/**
* 发送inform消息
* @param target
* @param variables
* @return
* @throws IOException
*/
private boolean sendInform(Target target, List<VariableBinding> variables) throws IOException {
PDU pdu = new PDU();
for(VariableBinding vb : variables) {
pdu.add(vb);
}
ResponseEvent response = snmp.inform(pdu, target);
if(response==null)
return true;
if(response.getResponse()==null)
return false;
if(response.getError()!=null)
return false;
return true;
}
public boolean sendTrap(Target target) throws IOException {
List<VariableBinding> variables = getVariable();
return sendTrap(target, variables);
}
/**
* 发送trap消息
* @param target
* @param variables
* @return
* @throws IOException
*/
private boolean sendTrap(Target target, List<VariableBinding> variables) throws IOException {
PDU pdu = new PDU();
pdu.setType(PDU.TRAP);
for(VariableBinding vb : variables) {
pdu.add(vb);
}
snmp.send(pdu, target);
return true;
}
}
最后,我们再编写一个测试类
package main;
import main.snmp.util.InformReceiver;
import main.snmp.util.InformSender;
import org.snmp4j.Target;
import org.snmp4j.TransportMapping;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.OctetString;
import java.io.IOException;
import java.util.List;
public class Main {
public static void main(String[] args){
//在本机10062端口启动监听
InformReceiver receiver = new InformReceiver(10062);
receiver.startListener();
System.out.println("snmp start listener");
try {
Thread.sleep(1000);
} catch (InterruptedException e) { }
InformSender sender = new InformSender();
try {
sender.Connect();
Target target = InformSender.getTargetV2("tcp:127.0.0.1/10062","");
//发送inform
boolean result = sender.sendInform(target);
if(result==true)
System.out.println("snmp send inform succ.");
else
System.out.println("snmp send inform fail.");
//发送trap,trap只管发送不管结果
result = sender.sendTrap(target);
if(result)
System.out.println("snmp send trap succ.");
else
System.out.println("snmp send trap fail.");
} catch (IOException e) {
e.printStackTrace();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) { }
}
}
程序的运行结果
如果需要工程,可以去github下载,下载链接是https://github.com/skyfinging/snmp-Inform-demo