`
cuisuqiang
  • 浏览: 3936625 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
3feb66c0-2fb6-35ff-968a-5f5ec10ada43
Java研发技术指南
浏览量:3651118
社区版块
存档分类
最新评论

SNMP 使用SNMP4J V2进行TRAP

阅读更多

SNMP trap(SNMP 陷阱):某种入口,到达该入口会使SNMP被管设备主动通知SNMP管理器,而不是等待SNMP管理器的再次轮询!

 

在网管系统中,被管理设备中的代理可以在任何时候向网络管理工作站报告错误情况,例如预制定阈值越界程度等等。代理并不需要等到管理工作站为获得这些错误情况而轮询他的时候才会报告。这些错误情况就是众所周知的SNMP自陷(trap)!

 

网管系统开放监听端口,始终监听被管设备对于该端口的通信信息。被管设备发生故障会主动向该端口发送故障信息,网管系统收到消息进行告警!

 

首先要模拟工作站对端口进行监听,请看如下程序:

package t3;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Vector;
import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.mp.MPv3;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TcpAddress;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;

/**
 * 本类用于监听代理进程的Trap信息
 */
public class MultiThreadedTrapReceiver implements CommandResponder {
	
	public static void main(String[] args) {
		MultiThreadedTrapReceiver multithreadedtrapreceiver = new MultiThreadedTrapReceiver();
		multithreadedtrapreceiver.run();
	}

	private MultiThreadedMessageDispatcher dispatcher;
	private Snmp snmp = null;
	private Address listenAddress;
	private ThreadPool threadPool;

	public MultiThreadedTrapReceiver() {
	}
	
	public void run() {
		try {
			init();
			snmp.addCommandResponder(this);
			System.out.println("--------------->开始监听Trap信息!<---------------");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
	private void init() throws UnknownHostException, IOException {
		threadPool = ThreadPool.create("Trap", 2);
		dispatcher = new MultiThreadedMessageDispatcher(threadPool,new MessageDispatcherImpl());
		listenAddress = GenericAddress.parse(System.getProperty("snmp4j.listenAddress", "udp:127.0.0.1/2008")); // 本地IP与监听端口
		TransportMapping transport;
		// 对TCP与UDP协议进行处理
		if (listenAddress instanceof UdpAddress) {
			transport = new DefaultUdpTransportMapping((UdpAddress) listenAddress);
		} else {
			transport = new DefaultTcpTransportMapping((TcpAddress) listenAddress);
		}
		snmp = new Snmp(dispatcher, transport);
		snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1());
		snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());
		snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3());
		USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
		SecurityModels.getInstance().addSecurityModel(usm);
		snmp.listen();
	}

	/**
	 * 实现CommandResponder的processPdu方法, 用于处理传入的请求、PDU等信息
	 * 当接收到trap时,会自动进入这个方法
	 */
	@SuppressWarnings("unchecked")
	public void processPdu(CommandResponderEvent respEvnt) {
		// 解析Response
        if (respEvnt != null && respEvnt.getPDU() != null) {
        	Vector<VariableBinding> recVBs = respEvnt.getPDU().getVariableBindings();
           	for (int i = 0; i < recVBs.size(); i++) {
            	VariableBinding recVB = recVBs.elementAt(i);
               	System.out.println(recVB.getOid() + " : " + recVB.getVariable());
      		}
		}
	}
}

 

我们采用的是实现 CommandResponder 接口,该接口有一个方法

public void processPdu(CommandResponderEvent respEvnt) 

 

在该端口接收到信息时会主动调用该方法!

运行Main方法,控制台提示

-------------->开始监听Trap信息!<---------------

 

程序对本机端口 2008 开始监听!

使用命令

>netstate -an

 

发现本机UDP端口已经开始监听!

 

我们再来实现Agent,被管设备向网管系统TRAP信息:

package t3;

import java.io.IOException;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
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;

/**
 * 本类用于向管理进程发送Trap信息
 */
public class SnmpUtilSendTrap {

	private Snmp snmp = null;
	private Address targetAddress = null;
	
	public static void main(String[] args) {
		try {
			SnmpUtilSendTrap util = new SnmpUtilSendTrap();
			util.initComm();
			util.sendPDU();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void initComm() throws IOException {
		// 设置管理进程的IP和端口
		targetAddress = GenericAddress.parse("udp:127.0.0.1/2008");
		TransportMapping transport = new DefaultUdpTransportMapping();
		snmp = new Snmp(transport);
		transport.listen();
	}

	/**
	 * 向管理进程发送Trap报文
	 * 
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public void sendPDU() throws IOException {
		// 设置 target
		CommunityTarget target = new CommunityTarget();
		target.setAddress(targetAddress);
		// 通信不成功时的重试次数
		target.setRetries(2);
		// 超时时间
		target.setTimeout(1000 * 5);
		// snmp版本
		target.setVersion(SnmpConstants.version2c);
		// 创建 PDU
		PDU pdu = new PDU();
		pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.6.0"),new OctetString("aaaa")));
		pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.2.0"),new OctetString("bbbb")));
		pdu.setType(PDU.TRAP);
		// 向Agent发送PDU,并接收Response
		snmp.send(pdu, target);
		System.out.println("------------> END<--------------");
	}	
}

 

使用的SNMP版本应该是 V2,V1的操作与V2 TRAP不同!

运行后控制台打印运行结束!

网管系统模拟端打印收到的OID和OID对应的值信息!

 

请您到ITEYE看我的原创:http://cuisuqiang.iteye.com

或支持我的个人博客,地址:http://www.javacui.com

 

1
1
分享到:
评论
7 楼 cuisuqiang 2014-06-04  
KuhYygy 写道
请问下楼主,如果trap里的包含中文的信息,应该如何解码,准确来讲,应该如何选择字符编码?

String s = new String(((OctetString)recVB.getVariable()).getValue(), "UTF-8");

如上,我看有些写UTF-8,有些写GBK,请问这个应该怎么选择,或者有其它的方法解释出trap里的中文?谢谢~

如果是我们俩之间做通信,咱俩之间肯定知道字符串是什么编码格式的,为什么会出现不知道编码的情况?
6 楼 KuhYygy 2014-06-03  
请问下楼主,如果trap里的包含中文的信息,应该如何解码,准确来讲,应该如何选择字符编码?

String s = new String(((OctetString)recVB.getVariable()).getValue(), "UTF-8");

如上,我看有些写UTF-8,有些写GBK,请问这个应该怎么选择,或者有其它的方法解释出trap里的中文?谢谢~
5 楼 lanqiu17 2014-02-21  
cuisuqiang 写道
lanqiu17 写道
  @SuppressWarnings("unchecked") 
    public void processPdu(CommandResponderEvent respEvnt) { 
        // 解析Response 
        if (respEvnt != null && respEvnt.getPDU() != null) { 
            Vector<VariableBinding> recVBs = respEvnt.getPDU().getVariableBindings(); 
            for (int i = 0; i < recVBs.size(); i++) { 
                VariableBinding recVB = recVBs.elementAt(i); 
                System.out.println(recVB.getOid() + " : " + recVB.getVariable()); 
            } 
        } 
    }

楼主,我觉得这里应该交给线程去处理。它占用的是接收trap线程池中的线程,会阻塞trap消息的接收

SNMP4J用的是堵塞线程池处理,既然已经有线程池处理了,为什么再做一层线程处理?除非是担心收到的消息很长时间处理不掉,那增大SNMP线程池就可以了


但当管理设备过多,并且发送trap消息频繁时,增大snmp线程池只是将问题延后了
4 楼 cuisuqiang 2014-02-20  
lanqiu17 写道
  @SuppressWarnings("unchecked") 
    public void processPdu(CommandResponderEvent respEvnt) { 
        // 解析Response 
        if (respEvnt != null && respEvnt.getPDU() != null) { 
            Vector<VariableBinding> recVBs = respEvnt.getPDU().getVariableBindings(); 
            for (int i = 0; i < recVBs.size(); i++) { 
                VariableBinding recVB = recVBs.elementAt(i); 
                System.out.println(recVB.getOid() + " : " + recVB.getVariable()); 
            } 
        } 
    }

楼主,我觉得这里应该交给线程去处理。它占用的是接收trap线程池中的线程,会阻塞trap消息的接收

SNMP4J用的是堵塞线程池处理,既然已经有线程池处理了,为什么再做一层线程处理?除非是担心收到的消息很长时间处理不掉,那增大SNMP线程池就可以了
3 楼 lanqiu17 2014-02-20  
  @SuppressWarnings("unchecked") 
    public void processPdu(CommandResponderEvent respEvnt) { 
        // 解析Response 
        if (respEvnt != null && respEvnt.getPDU() != null) { 
            Vector<VariableBinding> recVBs = respEvnt.getPDU().getVariableBindings(); 
            for (int i = 0; i < recVBs.size(); i++) { 
                VariableBinding recVB = recVBs.elementAt(i); 
                System.out.println(recVB.getOid() + " : " + recVB.getVariable()); 
            } 
        } 
    }

楼主,我觉得这里应该交给线程去处理。它占用的是接收trap线程池中的线程,会阻塞trap消息的接收
2 楼 lanqiu17 2014-02-20  
哥们, 你也是做网管软件的啊 , 能交流下吗
1 楼 cuisuqiang 2012-06-05  
如果Trap时需要给客户端返回一些信息,可以参考如下代码:
	/**
	 * 实现CommandResponder的processPdu方法, 用于处理传入的请求、PDU等信息
	 * 当接收到trap时,会自动进入这个方法
	 */
	@SuppressWarnings("unchecked")
	public void processPdu(CommandResponderEvent respEvnt) {
		List<VariableBinding> list = new ArrayList<VariableBinding>();
		// 解析Response
	    if (respEvnt != null && respEvnt.getPDU() != null) {
	    	Vector<VariableBinding> recVBs = respEvnt.getPDU().getVariableBindings();
	       	for (int i = 0; i < recVBs.size(); i++) {
	        	VariableBinding recVB = recVBs.elementAt(i);
	           	System.out.println(recVB.getOid() + " : " + recVB.getVariable());
	           	Random random = new Random();
	           	list.add(new VariableBinding(recVB.getOid(),new Integer32(random.nextInt(1999))));
	  		}        	
	       	org.snmp4j.mp.StatusInformation statusInformation = new org.snmp4j.mp.StatusInformation();
			org.snmp4j.mp.StateReference ref = respEvnt.getStateReference();
			try {
				// 创建 PDU
				PDU vPDU = respEvnt.getPDU();
				vPDU.setType(PDU.RESPONSE);
				Random random = new Random();
				for(int i = 0;i< list.size() ;i++){
					VariableBinding vb = list.get(i);
					vb.setVariable(new Integer32(random.nextInt(9999)));
					vPDU.set(i,vb);
				}
				respEvnt.getMessageDispatcher().returnResponsePdu(
						respEvnt.getMessageProcessingModel(),
						respEvnt.getSecurityModel(),
						respEvnt.getSecurityName(),
						respEvnt.getSecurityLevel(), 
						vPDU,
						respEvnt.getMaxSizeResponsePDU(), 
						ref,
						statusInformation);
			} catch (Exception e) {
				e.printStackTrace();
			}          	
		}
	}

相关推荐

    snmp4j实现snmp trap 发送与接收

    snmp4j 实现snmp trap发送与接收

    Java使用SNMP4J实现snmp trap接口发送消息_20170808_LK

    Java使用SNMP4J实现snmp trap接口发送消息_20170808_LK

    Python利用SNMP读取交换机端口信息及状态

    Python利用SNMP读取交换机端口信息及状态,通过路由器和交换机上启用SNMP协议,Python环境下安装net-snmp-python包实现

    Linux snmp模拟器(v1、v2、v3)

    基于Linux的snmpd模拟器,可用于模拟网络设备的snmp采集,对于网管软件的测试非常实用。

    gosnmptrap:用go(golang)编写的snmp陷阱服务器

    Snmp V2陷阱 安装 最简单的安装方法是通过go get: go get github.com/ebookbug/gosnmptrap 例子 package main import ( "fmt" "net" "github.com/ebookbug/gosnmptrap" ) func main() { fmt.Println("Start a ...

    SNMP协议基础,网络学习必备

    2 SNMP V1和SNMP V2 4 2.1 SNMP 和 UDP 5 2.2 SNMP community 5 2.3 管理信息结构 5 2.3.1 OID命名 6 2.3.2 OID的描述 7 2.4 V2版本中的SMI扩展 13 2.5进一步了解MIB-II 15 2.6 SNMP 操作 17 2.6.1 get 17 2.6.2 ...

    C#开发的SNMP类库

    使用C#开发的SNMP类库。 运行环境:.NET 4.0、Mono 2.8。 类库符合公共语言规范 (CLS),代码遵守微软公共许可(MS-PL)。 支持SNMP V1, V2, V3。 可以发送GetRequest、SetRequest等SNMP请求,并接收返回消息。 可以...

    PowerTCP SNMP Tool Suite—可方便构造、处理SNMP的网络控

    · 包含一组支持对象(DartStream、SnmpMessage、SnmpTable、SnmpTableRow、 SnmpTrap、 SnmpTraps、SnmpVariable、 SnmpVariables),它们提供了一个对象模式,可以为专家以及新手简化SNMP运用。 · 支持 ...

    snmp agent开发包

    各种操作包括get,getnext,getbulk,set和v1,v2两种Trap。用户编写程序时不需考虑协议 细节,程序框架由mib编译器自动生成,使用时,只要在框架中填入应用相关的逻辑即可。 windows版本可以支持的编译器: ms ...

    使用C#编写的SNMP类库

    使用C#开发的类库,使用SNMP协议交互消息。 运行环境:.net 4.0或mono 2.8。 支持SNMP V1,V2,V3。 可以发送Get,Set等请求,并获取回应。 可以发送,接收Trap。 可以接收SNMP请求,并反馈回应。 代码内有中文注释,...

    HiliSoftSNMPMIBBrowser中文版

    HiliSoftSNMPMIBBrowser中文版软件... 使用这两个视图,用户可以非常容易地通过SNMPv1/v2c/v3协议来浏览和修改SNMP代理上变量的值。内建有trap receiver,可以收集SNMP代理发送的trap。 是你学习snmp协议的好帮手好工具

    推荐SNMP探测工具

    HiliSoft出品的SNMP MIB Browser(MIB浏览器),功能强大,简单易用。 1. 支持SNMP v1, v2c & v3 2. 支持SMI v1 & v2 3. 支持Get/GetNext/Set/GetBulk/Walk 4. 内建Trap接收器 5. 快速解析、加载MIB文件

    node-red-contrib-snmp-trap-listener:接收到陷阱事件时发出事件的节点

    过滤器选项为: SNMP版本(v1,v2c,v3) 社区字符串(仅适用于v1和v2c) 用户凭证(仅v3) IP过滤 入门 -Node-RED文档在部署更改之前,请记住先配置snmp-trap-listener节点。 文献资料 输入 snmp-trap-listener...

    使用C#开发的SNMP类库

    使用C#编写,可以在.net 4.0,mono 2.8下使用。...支持SNMP V1, V2, V3。 可以发送SNMP请求并接收回应。 可以发送接收TRAP。 可以接收SNMP请求并发送回应。 代码中文注释。 http://snmpmessenger.codeplex.com/

    logstash-snmpout:Logstash 的 SNMP 输出

    Logstash 的 SNMP 陷阱 v2c 输出 #概要 output { snmptrap { codec =&gt; ... # codec (optional), default: "line" host =&gt; ... # string (optional), default: "0.0.0.0" port =&gt; ... # number (optional), ...

    ruby-snmp:SNMP的Ruby实现(简单网络管理协议)

    此版本支持以下内容: GetRequest,GetNextRequest,GetBulkRequest,SetRequest,响应SNMPv1_Trap,SNMPv2_Trap和通知PDU SNMPv1和SNMPv2c定义的所有ASN.1数据类型发送通知以及v1和v2陷阱陷阱处理信息以及v1和v2...

    fluent-plugin-process-snmptrap:这是一个流利的过滤器插件,用于过滤从服务器接收的SNMP陷阱

    这是用于SNMP V2陷阱的筛选器插件。 该插件检查SNMP消息,并在SNMP陷阱中映射OID和关联的值。 它将机器ID,事件,SNMP陷阱类型,主机,机器状态,严重性,设备和消息添加到接收到的事件中。 它根据以下格式检测SNMP...

    puresnmp:纯Python SNMPv2库

    而不是实施ASN.1解析,而是对与SNMP相关的ASN.1和X.690信息进行硬编码(请记住,所有硬编码的内容均已定义好)。 当然可以将这个程序包包装到另一个程序包中,从而增加MIB解析和处理能力。 但是,这已经超出了本...

    Tcl SNMP Tools-开源

    一个 Tcl 包,提供用于管理远程代理的 SNMP 工具。 它使用 NetSNMP 库并支持所有标准 SNMP v1/v2/v3 操作和更多操作:get、set、getnext、walk、bulkget、bulkwalk、trap、translate 和 table。

Global site tag (gtag.js) - Google Analytics