SNMP协议以及JAVA实战代码展示

SNMP协议以及代码实现
主要是为了实现:Java通过SNMP协议和交换机进行交互
JAVA开发SNMP明细

第一步:
(1)首先安装SNMP服务。 (控制面板→添加与删除工具→添加与删除组件→管理和监视工具→详细信息→选择“简单网络管理协议”→确定)。
(2)启动snmp服务。
(3)下载snmp4j.jar
(4)新建项目,加如snmp4j.jar,编写代码
编写的代码中需要的内容:
(1)枚举网元类型(目前只有一种类型:摄像机类型)
(2)封装网元的基本属性(可操作属性、可返回属性等)
(3)封装target。(连接时网元的地址、端口、传输协议、共同体等)
(4)封装PDU数据包
(5)封装网元过滤规则。(通过一些表达式来限定处理网元的范围)
(6)检测中心。(包含重连操作和检测线程)
(7)心跳中心。(心跳检测线程)
(8)封装Get-Request。(命令发送和监听Response返回的线程)
(9)监听Trap报告。(监听162端口)
(10)封装Trap报告
(11)主线程。(入口,入则启动各项所需线程)

Java开发中SNMP的运行流程:
(1)程序入口在主线程,主线程启动后,在加载一些配置和启动其他的一些明细线程(心跳线程、检测中心线程、trap监听等)。
(2)Trap监听(同步到线程)运行后,会在工作站的162端口监听从网元发送来的告警信息,并将告警信息添加进告警列表内,同时
在Trap监听接口里实现清除告警方法。
(3)Get—Request接口里有向网元发送命令的方法和监听Response返回信息的线程。(发送命令关联Response监听)
(4)心跳线程运行后,会不断的验证当前连接正常的网元列表。(Get-Request和Trap的时候,成功交互会向正常网元列表添加网元)
[无重复添加],异常则移除,并在重连列表添加网元。
(5)重连检测中心线程运行起来后,会不断验证当前连接不正常的列表是否回复连接。(Get—Request和Trap的时候,成功交互会修改网元属性的连接状态为成功连接),
将依然断连的网元进行重连。

SNMP的具体部署:

  1. snmp和交换机之间进行的交互:去监控交换机的网络传输速度、网络输出速度、发送包数、接受包数。
    (1)其中涉及到的变量:
    ① private String IP //需要检测的IP地址
    ② private int version; //对象的snmp的版本号
    ③ private String port; //要检测的对象的端口号,一般是161
    ④ private String OID; //检测对象的OID值
    ⑤ private String community = “public”; //设定共用体

代码实例;
//获取到交换机给的信息,发送不同的oid值,对应的消息不同
public class SnmpData {

//定义部分常量
public static final int DEFAULT_VARSION = SnmpConstants.version2c;
//采用的协议
public static final String DEFAULT_PROTOCOL = "udp";
//请求的端口号
public static final int DEFAULT_PORT = 161;
//请求超时的时间
public static final long DEFAULT_TIMEOUT = 3 * 1000L;
//失败之后请求次数
public static final int DEFAULT_RETRY = 3;

/*
 * 创建对象communityTarget
 */
public static CommunityTarget createDefualt(String ip,String community){
	//定义本机地址
	Address address = GenericAddress.parse(DEFAULT_PROTOCOL+":"+ip+"/"+DEFAULT_PORT);
	//设定CommunityTarget类
	CommunityTarget target = new CommunityTarget();
	//设置snmp共同体
	target.setCommunity(new OctetString(community)); //获取到系统中的默认配置的属性,在服务中的安全下边可以进行配置
    target.setAddress(address);
    //设置超时重试次数
    target.setRetries(DEFAULT_RETRY);
	//设置超时的时间
    target.setTimeout(DEFAULT_TIMEOUT);
	//设置使用的snmp的版本
    target.setVersion(DEFAULT_VARSION);
	return target;
}

/*
 * 获取单个oid对应的信息
 */
public static void snmpGet(String ip,String community,String oid){
	//设定CommunityTarget类
	CommunityTarget target = createDefualt(ip, community);
	Snmp snmp = null;
	try {
		//创建请求的PDU 获取到MIB
		PDU pdu = new PDU();
		//通过调用add的方法来绑定要查询的OID
		pdu.add(new VariableBinding(new OID(oid)));
		//设定传输协议为UDP
		DefaultUdpTransportMapping transport = new DefaultUdpTransportMapping();
		//创建snmp对象是为了的发送请求
	    snmp = new Snmp(transport);
	    //启动监听进程,接受消息
	    snmp.listen();
	    System.out.println("---------->发送PDU<------------");
   	    //调用setType();方法来确定PDU的类型
	    pdu.setType(PDU.GET);
	    //snmp类调用send  将准备好的target 和 pdu 进行发送,返回一个ResponseEvent对象
	    ResponseEvent event = snmp.send(pdu, target);
	    System.out.println("PeerAddress:"+event.getPeerAddress());
        //通过ResponseEvent对象来获取到回应的pdu ,event.getResponse()
	    PDU response = event.getResponse();
	    if(response == null){
	 	    System.out.println("response is null,request time out");
	    }else{
	 	    System.out.println("response pdu size is "+response.size());
		    for(int i = 0; i < response.size();i++){
                //获取到的对象的的类型是VariableBinding,通过get(index)可以获取到MIB信息(之前绑定的OID的值)
			    VariableBinding vb = response.get(i);
			    System.out.println(vb.getOid()+" = "+vb.getVariable());
		    }
	    }
	    System.out.println("SNMP GET one OID value finished!");
	 } catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
		System.out.println("SNMP GET EXCEPTION:"+e);
	}finally{
	    if(snmp!=null){
	    	try {
				snmp.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	    }	
	}
}

}

  1. 设置共用体的时候注意:private String community = “public”; //设定共用体
    其中共用体是你在服务中进行配置的在本机电脑中的操作是:
    ①在服务中查找到SNMP Service,点击右键属性
    ②在列表头部中找到安全一栏,下方有接受的社区名称。
    ③添加相对应的社区名称即可。

  2. SNMP4j的介绍
    (1)是一个用Java来实现SNMP(简单网关协议)协议的开源项目,它支持命令行形式的管理与响应。
    SNMP4j是纯面向对象涉及与SNMP++(用c++来实现)类似。
    (2)特性: 注意其中全部均为PDU格式。

4.SNMP4j中重点类和接口
(1)SNMP类:
该类是SNMP4j中最为核心的类,负责snmp报文的接受和发送,提供了发送和接受PDU的方法,
所有类型的PDU都可以被同步或者异步被发送。
(2)PDU类和ScopePDU类:
该类是SNMP报文单元的抽象,其中PDU类适用于SNMPv1和SNMPv2c,ScopePDU类继承于PDU类,适用于SNMPv3;
(3)Target接口和CommunityTarget类以及UserTarget类
对应于SNMP代理的地址信息,包括IP地址和端口号(161)。其中Target接口适用于SNMPv1和SNMPv2c。CommunityTarget实现了Target接口,用于
SNMPv1和SNMPv2这两个版本,UserTarget类实现了Target接口,适用于SNMPv3。
(4)TransportMapping接口
该接口代表SNMP4j所使用的传输层协议。这也是SNMP4j一大特色的地方。按照RFC的规定;SNMP是只是用UDP作为传输层协议的。而SNMP4j支持管理端和代理
端使用UDP或者TCP进行传输。该接口有两个子接口。
(5)Snmp、Target、PDU三者的关系
Target代表远程设备或者远程实体、PDU代表端同Target通信的数据,Snmp就代表管理者管理功能(其实就是数据的收发)的具体执行者。
打个比方:Target是远程的交换机,PDU是一个存储两者之间进行交互的信封,SNMP是进行传递“信封”的“邮差”。

  1. SNMP4j中的两种消息发送模式
    (1)同步发送模式也被称为阻塞模式:当管理者发送出一条消息之后,线程会被阻塞,查到对方的回应或者时间超时。同步发送模式编程较为简单,但不适用于发送广播消息。
    (2)异步发送模式也被为非阻塞模式:当程序发送一条消息之后,线程会继续执行,当收到消息的回应的时候,程序会对消息做出相对应的回应处理。
    要实现异步发送模式,需要实例化一个实现了ResponseListener接口的类的对象。ResponseListener接口中有一个名为onResponse的函数,这是一个回调函数,
    当程序收到响应的时候,会自动调用该函数完成对响应的处理。

6.使用SNMP4J实现管理端的步骤
(1)第一步:初始化
①明确SNMP在传输层所使用的协议
一般情况下,我们都使用UDP协议作为SNMP在传输层的协议,所以我们需要实例化的对应是一个DefaultUdpTransportMapping接口对象。
②实例化一个snmp对象
在此过程中,我们需要将1中实例化的DefaultUdpTransportMapping接口的对象作为参数,穿snmp类的构造函数中。另外如果实现的SNMPv3协议,我们还需要设置安全
机制,添加安全用户等等。
③在此,我们可以调用刚刚实例化的DefaultUdpTransportMapping的接口对象的listen方法,让程序监听snmp消息。

(2)第二步:构造发送目标
如果实现的是SNMPv2c或者说是SNMPv1的报文,我们需要实例化一个CommunityTarget对象。如果实现的是SNMPv3的程序,我们则需要实例化一个UserTarget类的对象。
之后我们还需要对实例化的对象做一些设置。如果CommunityType的对象,则需要设置使用的SNMP的版本,重传时间和等待时延。如果是UserTarget对象我们
不仅仅是需要设置版本、重传时间、等待时延,还需要设置安全级别和安全名称。

(3)第三步:构造发送报文
如果实现的是SNMPv2c或者说是SNMPv1的报文,我们需要实例化一个PDU对象。如果发送的是SNMPv3的报文,我们则需要实例化一个ScopedPDU类的对象。
之后我们还需要生成一个OID的对象。其中包含了我们需要从获取SNMP对象在MIB库中的ID。然后我们需要将OID和之前生成的PDU对象或者是ScopedPDU对象绑定,
并且设置PDU的报文类型(五中SNMP报文类型之一)。

(4)第四步:构造响应监听对象(异步模式)
当使用异步模式的时候,我们需要实例化一个实现了ResponseListener接口的对象,作为响应消息的监听对象。在构造该对象的过程中,我们需要重写
ResponseListener的OnResponse函数,该函数是一个回调函数,用来处理程序收到响应后的一些操作。

(5)第五步:发送消息
当所有上述操作都设置完毕之后,就可以发送消息了。同步模式和一步模式发送消息调用的函数名字均为send,但是两个函数所需参数不一样。同步模式的参数
仅为4.2和4.3中构造函数的目标对象和报文对象,而异步模式还需要4.4中构造的监听对象。
同步模式发送消息后便等待响应的到达,到达之后会但会一个ResponseEvent对象,该对象中包含了响应的相应信息。
异步模式发送消息之后便会继续执行,当收到响应消息的时,便会调用监听对象的OnResponse函数。该函数中的语句便是我们对响应的处理。

7.使用SNMP4J实现管理端的编码实现

(1)设定远程实体
snmp4j中,用CommunityTarget对象来表示远程实体(要进行snmp消息通信的远程主机,使用snmp的v2版本)。
(2)指定远程实体的地址
snmp4j中使用Address接口对象来表示,Address对象需要通过实现该接口的类的对象向上转型来实例化。
(3)通过CommunityTarget以及其父类接口中提供的setXXX方法来设定远程实体的属性,
如设定远程实体的snmp共同体属性、远程实体的地址、超时时间、重传次数、snmp版本等
(4)设定使用的传输协议
snmp4j中,用TransportMapping接口的对象来表示传输协议(tcp/udp)
(5)调用TransportMapping中的Listener()方法,启动监听进程,接受消息,由于该监听是守护进程,最后应调用close()方法来释放该进程
(6)创建SNMP对象,用于发送请求PDU
a、创建请求pdu,即创建PDU类的对象,调用PDU类中的add()方法绑定要查询的OID,调用PDU中的setType()方法来确定该pdu的类型(与snmp中五中操作相对应)。
b、通过pdu的构造方法,public SNMP(TransportMapping transportMapping),或者其他构造方法来生成pdu,之后调用ResponseEvent send(PDU pdu,Target target)
发送pdu,该方法返回一个ResponseEvent对象。
(7)通过ResponseEvent对象来获得SNMP请求的应答pdu,方法:public PDU getResponse()
(8)通过应答pdu获得到MIB信息(之前绑定的OID的值)方法:VarbleBinding getResponse()

8.如何查看 一个端口号被占用并且关闭正在运行的程序
① cmd
② 在命令行中输入netstat -ano 回车
可以查看到本机中所有正在运行的进程,将本地地址后的最后一位记录下来 例如:本机地址为:0.0.0.49157
③ 查看被占用的端口号对应的PID值 输入命令: netstat -aon|findstr “49157” 回车 记录下来对应的PID值(2720)
④ tasklist|findstr “2720” 即可展示出正在使用端口号的程序。
⑤ 结束进程 taskkill /f /t /im 进程名 如:UDP.exe

具体代码逻辑

package com.ext.snmp;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
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;

import com.ext.db.JDBC;
import com.ext.domain.AlcatelLucent;
import com.ext.domain.Avaya;
import com.ext.domain.Record;
import com.ext.domain.Siemens;
import com.ext.domain.Warn_info_send;
import com.ext.domain.Zte;
import com.ext.snmp.consts.AlcatelLucentSnmpConst;
import com.ext.snmp.consts.AvayaSnmpConst;
import com.ext.snmp.consts.RecordSnmpConst;
import com.ext.snmp.consts.SiemensSnmpConst;
import com.ext.snmp.consts.ZteSnmpConst;
import com.ext.snmp.utils.MessageEndpointUtils;
import com.ext.utils.Tools;

/**
 * 本类用于监听代理进程的Trap信息
 */
public class SnmpTrapReceiver implements CommandResponder {
	private static String ip = null;//客户端IP地址,不能是127.0.0.1
	private static String port = null;//监听端口
	private static String charset = null;//snmp编码集
	
	/**
	 * 加载和snmp相关的属性信息
	 */
	static {
		 ip = Tools.getProperties("config/snmp.properties","client_ip");//获取到监听的IP地址
         port = Tools.getProperties("config/snmp.properties", "client_port");//获取到监听的端口号
         charset = Tools.getProperties("config/snmp.properties", "snmp_charset");  //获取到编码集     
	}

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

	public SnmpTrapReceiver() {
		// BasicConfigurator.configure();
	}

	/**
	 * 初始化snmp服务
	 * @throws UnknownHostException
	 * @throws IOException
	 */
	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:" + ip + "/" + port)); // 本地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();
	}

	public void run() {
		try {
			init();
			snmp.addCommandResponder(this);
			System.out.println("SnmpTrap开始监听信息...");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 实现CommandResponder的processPdu方法, 用于处理传入的请求、PDU等信息 当接收到trap时,会自动进入这个方法
	 * @param respEvnt
	 */
	// 解析Response
	public void processPdu(CommandResponderEvent respEvnt) {
		if (respEvnt != null && respEvnt.getPDU() != null) {
			//记录日志需要的消息
			//消息发送过来的IP地址和端口
			String peerAddress = respEvnt.getPeerAddress().toString();
			//trap信息中携带的变量信息
			//String variableBindings = parStr(respEvnt.getPDU().getVariableBindings().toString());
			String loginfo = "=== > 接收到的trap信息:[发送来源="+peerAddress+", 携带的变量= \"";
			//获取到一个包含有全部oid值的对象
			@SuppressWarnings("unchecked")
			Vector<VariableBinding> recVBs = respEvnt.getPDU().getVariableBindings();    
			String message = null;
		
			//目的是进行进行拼接日志信息,将十六进制进行表示的信息转化为汉字形式
			for(VariableBinding rec:recVBs){
				if(!"1.3.6.1.4.1.39871.6.100.1".equals(rec.getOid().toString())){   //录音系统的如果发送过来的是十六进制需要进行特殊处理
					loginfo =  loginfo +rec.getOid().toString() + " = "+parStr(rec.getVariable().toString()) + ";";	
				}else{
					loginfo =  loginfo +rec.getOid().toString() + " = "+ chageStr(rec.getVariable().toString()) + ";";
				}
			}
			loginfo = loginfo +"\"] ";
			
			//将对象中的所有的oid值全部都获取出来,与固定的字符串1.3.6.1.6.3.1.1.4.1.0进行对比,如果包含将该oid值对应的消息赋值给msg
			boolean recordFlag = false;
			for (int i = 0; i < recVBs.size(); i++) {
				VariableBinding recVB = recVBs.elementAt(i);				
				//东航过来的SNMP消息标识位
				if("1.3.6.1.6.3.1.1.4.1.0".equals(recVB.getOid().toString())){
					message = parStr(recVB.getVariable().toString()).replace(" ", "");
					recordFlag = true;
				}else if("1.3.6.1.6.3.1.1.4.1.0".equals(recVB.getOid().toString())){
					message = parStr(recVB.getVariable().toString());
					break;
				}
			}
			
			if(Tools.notEmpty(message)){
				//告警信息初始化
				Warn_info_send warn_info_send = new Warn_info_send();
				//获取当前时间,到秒
			    String now =  Tools.getDate();
			    //获取IP地址,不带端口号
			    String ipaddr = getIp(peerAddress);
			    //日期信息是否入库
			    boolean sendFlag = false;
			    int rSize = recVBs.size();
			    
				if("1.3.6.1.4.1.6889.2.73.9.0.4622".equals(message) 
						|| "1.3.6.1.4.1.6889.2.73.9.0.4992".equals(message)
						|| "1.3.6.1.4.1.6889.2.73.9.0.5952".equals(message)
						|| "1.3.6.1.4.1.6889.2.73.9.0.4972".equals(message)){
					//AVAYA交换机	
					Avaya snmpContext = new Avaya();
					//loginfo = "Avaya"+"=== > 接收到的trap信息:[发送来源="+respEvnt.getPeerAddress()+", 携带的变量="+parStr(respEvnt.getPDU().getVariableBindings().toString())+"] <=== \n";
					loginfo = "Avaya " + loginfo;
					
					for (int i = 0; i < rSize; i++) {
						VariableBinding recVB = recVBs.elementAt(i);
					    AvayaSnmpConst.setFiledValue(snmpContext, recVB.getOid().toString(), parStr(recVB.getVariable().toString()));
					}
					
					//告警信息初始化
					warn_info_send.setWtitle(snmpContext.getAvCmMessagingAlarmWtitle());
					String devType = "设备类型="+ Avaya.getWarnDevType(snmpContext.getAvCmMessagingAlarmEventName());
					String devLoc = "告警位置=" + Avaya.getWarnDevLoc(snmpContext.getAvCmMessagingAlarmEventID());
					String winfo = devType + "," +devLoc;
					
					warn_info_send.setWinfo(winfo);
					String level = changeColorMethod(snmpContext.getAvCmMessagingAlarmLevel()); 
					warn_info_send.setWlevel(level);
					//warn_info_send.setWlevel(snmpContext.getAvCmMessagingAlarmLevel());
					warn_info_send.setWsysname("Avaya");
					warn_info_send.setWsip(ipaddr);
					warn_info_send.setSnmpinfo(loginfo);
					//是否推送,0:告警入库,1:已恢复,2:忽略,3:已推送
					int flag = 0;
					//将数据推送事找人平台
					boolean  flagdata =  judgeAvaryLevelSend(snmpContext.getAvCmMessagingAlarmLevel());
					if(flagdata){
						String result = MessageEndpointUtils.send(snmpContext);
						snmpContext.setResult(result);
						flag = 3;
					}
					warn_info_send.setFlag(flag);
					sendFlag = true;
					
				}else if("1.3.6.1.4.1.637.64.0.10.1.2".equals(message)){
					//阿尔卡特朗讯交换机
					AlcatelLucent snmpContext = new AlcatelLucent();
					snmpContext.setAlAlarmIpAddress(ipaddr);
					//snmpContext.setAlAlarmDealWranLevel(alAlarmDealWranLevel);
					loginfo = "AlcatelLucent "+loginfo;
					for (int i = 0; i < rSize; i++) {
						VariableBinding recVB = recVBs.elementAt(i);
						//将获取的值放到对象对应的属性中
						AlcatelLucentSnmpConst.setFiledValue(snmpContext, recVB.getOid().toString(), parStr(recVB.getVariable().toString()));
					}
					
					//告警信息初始化
					//warn_info_send.setWtitle(Tools.isNull(snmpContext.getAlAlarmSwitchBoradNetName()));
					warn_info_send.setWtitle(Tools.isNull(snmpContext.getAlAlramExternal()));
					warn_info_send.setWinfo(snmpContext.getContext());
					String level = changeColorMethod(snmpContext.getAlAlarmDealWranLevel());
					warn_info_send.setWlevel(level);
					//warn_info_send.setWlevel(snmpContext.getAlAlarmDealWranLevel());
					warn_info_send.setWsysname("阿朗");
					warn_info_send.setWsip(ipaddr);
					
					warn_info_send.setSnmpinfo(loginfo);
					//是否推送,0:告警入库,1:已恢复,2:忽略,3:已推送
					int flag = 0;
					//将数据推送事找人平台
					boolean  flagdata =  judgeAlcateLucentLevelSend(snmpContext.getAlAlarmId());
					if(flagdata){
						String result = MessageEndpointUtils.send(snmpContext);
						snmpContext.setResult(result);
						flag = 3;
					}
					warn_info_send.setFlag(flag);
					sendFlag = true;
					
				}else if("1.3.6.1.4.1.4329.2.45.90.5".equals(message)){  
					//西门子的交换机
					Siemens snmpContext  = new Siemens();
					loginfo =  "Siemens "+loginfo;
					for (int i = 0; i < rSize; i++) {
						VariableBinding recVB = recVBs.elementAt(i);
						SiemensSnmpConst.setFiledValue(snmpContext, recVB.getOid().toString(), parStr(recVB.getVariable().toString()));
					}
					
					//告警信息初始化
					warn_info_send.setWtitle(snmpContext.getSiemensAlarmWtitle());
					warn_info_send.setWinfo(snmpContext.getSiemensAlarmExternal());  
					//String level = changeColorMethod(snmpContext.getSiemensAlarmLevel());
					String level =snmpContext.getSiemensAlarmLevel();
					warn_info_send.setWlevel(level);
					//warn_info_send.setWlevel(snmpContext.getSiemensAlarmLevel());
					warn_info_send.setWsysname("西门子");
					warn_info_send.setWsip(ipaddr);
					warn_info_send.setSnmpinfo(loginfo);
					//是否推送,0:告警入库,1:已恢复,2:忽略,3:已推送
					int flag = 0;
					//将数据推送事找人平台
					boolean  flagdata =  judgeSiemensLevelSend(snmpContext.getSiemensAlarmLevel());
					if(flagdata){
						String result = MessageEndpointUtils.send(snmpContext);
						snmpContext.setResult(result);	
						flag = 3;
					}
					warn_info_send.setFlag(flag);
					sendFlag = true;
					
				}else if("1.3.6.1.4.1.3902.701.1.1.50.4".equals(message)){
					//中兴交换机
					Zte snmpContext = new Zte();
					loginfo = "Zte " + loginfo;
					for (int i = 0; i < rSize; i++) {
						VariableBinding recVB = recVBs.elementAt(i);
						ZteSnmpConst.setFiledValue(snmpContext, recVB.getOid().toString(), parStr(recVB.getVariable().toString()));
					}
					//告警信息初始化
					warn_info_send.setWtitle(snmpContext.getZxEmsEventName());
					//warn_info_send.setWinfo(snmpContext.getZxEmsEventDescription());
					warn_info_send.setWinfo(snmpContext.getZxEmsEventName());
					//String level = changeColorMethod(snmpContext.getZxEmsEventSeverity());
					String level = snmpContext.getZxEmsEventSeverity();
					warn_info_send.setWlevel(level);
					//warn_info_send.setWlevel(snmpContext.getZxEmsEventSeverity());
					warn_info_send.setWsysname("中兴");
					warn_info_send.setWsip(snmpContext.getZxEmsEventserverIP());
					warn_info_send.setSnmpinfo(loginfo);
					//中兴交换机可以通过流水号判断告警事件唯一性,用于自动处理告警,将正在告警的告警如果已经恢复则自动处理
					warn_info_send.setWcode(snmpContext.getZxEmsEventAid());
					
					//是否推送,0:告警入库,1:已恢复,2:忽略,3:已推送
					int flag = 0;
					//将数据推送事找人平台
					boolean  flagdata = judgeZetLevelSend(snmpContext.getZxEmsEventSeverity());
					if(flagdata){
						String result = MessageEndpointUtils.send(snmpContext);
						snmpContext.setResult(result);	
						flag = 3;
					}
					warn_info_send.setFlag(flag);
					sendFlag = true;
					
				}else if(recordFlag){
					//录音系统
					Record snmpContext = new Record();
					snmpContext.setAlarmInfo(message);
					snmpContext.setAlarmType("INFO");
					loginfo = "Record " + loginfo;
					/**
					for (int i = 0; i < rSize; i++) {
						VariableBinding recVB = recVBs.elementAt(i);
						RecordSnmpConst.setFiledValue(snmpContext,recVB.getOid().toString(), parStr(recVB.getVariable().toString()));
					}	
					*/			
					warn_info_send.setWtitle(snmpContext.getAlarmInfo());
					warn_info_send.setWinfo(snmpContext.getAlarmInfo());
					//String level = changeColorMethod(snmpContext.getAlarmType());
					warn_info_send.setWlevel("7");
					//warn_info_send.setWlevel(snmpContext.getAlarmType());
					warn_info_send.setWsysname("录音系统");
					warn_info_send.setWsip(ipaddr);
					
					warn_info_send.setSnmpinfo(loginfo);
					//是否推送,0:告警入库,1:已恢复,2:忽略,3:已推送
					int flag = 0;
					//将数据推送事找人平台
					boolean  flagdata = judgeRecordLevelSend(snmpContext.getAlarmType());
					if(flagdata){
						String result = MessageEndpointUtils.send(snmpContext);
						snmpContext.setResult(result);
						flag = 3;
					}
					warn_info_send.setFlag(flag);
					sendFlag = true;
				}
				
				if(sendFlag){
					//JDBC连接数据库,将数据存储到数据库中
					JDBC jdbc = new JDBC();  
					String wcode = warn_info_send.getWcode();
					if(Tools.isEmpty(wcode)){
						wcode = "";
					}
					String insertFiled = "insert into warn_info_send (wtitle,winfo,wlevel,wsysname,wdate,wsip,flag,wcode,snmpinfo)";
					String insertValues = "values('"+warn_info_send.getWtitle()+"','"+warn_info_send.getWinfo()+"','"
							+warn_info_send.getWlevel()+"','"+warn_info_send.getWsysname()
							+"',to_timestamp('"+now+"','YYYY-MM-DD HH24:MI:SS'),'"
							+warn_info_send.getWsip()+"',"+warn_info_send.getFlag()
							+",'"+wcode+"','"+warn_info_send.getSnmpinfo()+"'"+")";
					String sql = insertFiled + insertValues;
					loginfo += ",JDBC UPDATE SQL=" + sql;
					jdbc.update(sql);
					jdbc.close();
				}else{
					loginfo = "未匹配到对应的交换机oid:" + loginfo;
				}
			}
			//日志信息写入文件
			extPrintLog(loginfo,"snmp");
		}
	}
	
	/**
	 * 当录音系统的告警消息是十六进制的时候
	 */
	private  String chageStr(String value) {
		String infoMessage = "";
		if(Tools.notEmpty(value)) {
			String info = value;
		    String []  strs =Tools.str2StrArray(info, ":");
		    String str =info.substring(strs[0].length()+1,info.length());
		    infoMessage = parStr(str);
		}
		return infoMessage;
	}

	/**
	 * 打印日志信息
	 */
	public static void extPrintLog(String loginfo,String logFileName) {
		String path = SnmpTrapReceiver.class.getResource("/").getPath();
		path = path.substring(0, path.indexOf("WEB-INF"));
		path = path + "/log/"+logFileName+".log";
		BufferedWriter bw = null;
		try {
			bw = new BufferedWriter(new FileWriter(path, true));
			bw.write(Tools.getDate()+"\t");
			bw.write(loginfo);
			bw.newLine();
			bw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(bw!=null) {
				try {
					bw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 十六进制转中文
	 * @author lxd
	 * @param value
	 * @return
	 */
	public static String parStr(String value) {
		String regex = "[0-9a-f]{2}(:[0-9a-f]{2})*";
		if(value.matches(regex)) {
			String[] strs = value.split(":");
			byte[] bys = new byte[strs.length];
			for (int i = 0; i < strs.length; i++) {
				bys[i] = (byte) Integer.parseInt(strs[i], 16);
			}
			try {
				value = new String(bys, charset);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		} 
		return value;
	}
	
	/**
	 * 获取到ip地址
	 */
    public String getIp(String ip){
    	String ipAddress = null;
    	String[] ss = ip.split("/");
    	ipAddress = ss[0];
    	return ipAddress; 
    }
	
    /**
     * 交换机的等级变化
     */
    public static String changeColorMethod(String colorNum){
    	String level = "";
    	String color = "colorNum";
    	if(color!=null&&!"".equals(color)){
    		if(colorNum.equalsIgnoreCase("Indeterminate")){
    			level = "0";			//不确定的
    		}else if(colorNum.equalsIgnoreCase("Critical")){
    			level = "1";						//关键的、严重的、极重要的
    		}else if(colorNum.equalsIgnoreCase("Error")){
    			level = "1";
    		}else if(colorNum.equalsIgnoreCase("Alarm")){
    			level = "1";
    		}else if(colorNum.equalsIgnoreCase("MAJ")){
    			level = "1";
    		}else if(colorNum.equalsIgnoreCase("Major")){
    			level = "2";							//重要的、主要的
    		}else if(colorNum.equalsIgnoreCase("Minor")){
    			level = "3";							//较小的
    		}else if(colorNum.equalsIgnoreCase("Warning")){
    			level = "4";						//一般警告
    		}else if(colorNum.equalsIgnoreCase("Warn")){
    			level = "4";						//警告
    		}else if(colorNum.equalsIgnoreCase("WRN")){
    			level = "4";						//警告
    		}else if(colorNum.equalsIgnoreCase("MIN")){
    			level = "4";				
    		}else if(colorNum.equalsIgnoreCase("Restored")){
    			level = "5";						//修复、归还、交还、使恢复
    		}else if(colorNum.equals("cleared")||colorNum.equals("Cleared")){
    			level = "6";						//变明朗、明白
    		}else if(colorNum.equalsIgnoreCase("Normal")){
    			level = "6";						//正常
    		}else if(colorNum.equalsIgnoreCase("Notification")){
    			level = "7";				//通知、通知单、布告、公布
    		}else if(colorNum.equalsIgnoreCase("Info")){
    			level = "7";			
    		}else if(colorNum.equalsIgnoreCase("Acknowledged")){
    			level = "8";			//告知已经收到
    		}else if(colorNum.equals("0")){
    			level = "0";
    		}else if(colorNum.equals("1")){
    			level = "1";
    		}else if(colorNum.equals("2")){
    			level = "2";
    		}else if(colorNum.equals("3")){
    			level = "3";
    		}else if(colorNum.equals("4")){
    			level = "4";
    		}else if(colorNum.equals("5")){
    			level = "5";
    		}else if(colorNum.equals("6")){
    			level = "6";
    		}else if(colorNum.equals("7")){
    			level = "7";
    		}else if(colorNum.equals("8")){
    			level = "8";
    		}else{
    			level = "6";
    		}
    	}else{
    		level = "6";
    	}
    	return level;
    }
    
    //改变中兴的告警等级
    public boolean judgeZetLevelSend(String level){
    	boolean flag = false;
    	if(level!=null){
    		if(level.equalsIgnoreCase("0")){
    			flag = true;
    		}else if(level.equalsIgnoreCase("1")){
    			flag = true;
    		}else if(level.equalsIgnoreCase("2")){
    			flag = true;
    		}else if(level.equalsIgnoreCase("3")){
    			flag = true;
    		}else if(level.equalsIgnoreCase("5")){
    			flag = true;
    		}
    	}
    	return flag;
    }
    
    //改变西门子的告警等级
    public boolean judgeSiemensLevelSend(String level){
    	boolean flag = false;
    	if(level!=null){
    		if(level.equalsIgnoreCase("0")){
    			flag = true;
    		}else if(level.equalsIgnoreCase("1")){
    			flag = true;
    		}else if(level.equalsIgnoreCase("2")){
    			flag = true;
    		}else if(level.equalsIgnoreCase("3")){
    			flag = true;
    		}
    	}
    	return flag;
    }
    
    
    //Avaya告警等级判断
    public boolean judgeAvaryLevelSend(String level){
    	boolean flag = false;
    	if(level!=null){
    		if(level.equalsIgnoreCase("MAJ")){
    			flag = true;
    		}else if(level.equalsIgnoreCase("MIN")){
    			flag = true;
    		}else if(level.equalsIgnoreCase("major")){
    			flag = true;
    		}else if(level.equalsIgnoreCase("minor")){
    			flag = true;
    		}
    	}
    	return flag;
    }
   
    //阿郎
    public boolean judgeAlcateLucentLevelSend(String alarmId){
    	boolean flag = false;
    	if(Tools.notEmpty(alarmId)){
    		/** 1125都是登录消息可以屏蔽,2018-10-25
    		if(alarmId.equals("1125")){
    			flag = true;
    		}else 
    		*/
    		if(alarmId.equals("2826")){
    			flag = true;
    		}else if(alarmId.equals("2043")){
    			flag = true;
    		}else if(alarmId.equals("2042")){
    			flag = true;
    		}else if(alarmId.equals("4108")){
    			flag = true;
    		}else if(alarmId.equals("310")){
    			flag = true;
    		}else if(alarmId.equals("2168")){
    			flag = true;
    		}else if(alarmId.equals("2019")){	//增加2019    hzw  2019-01-14
    			flag = true;
    		}
    	}
    	return flag;
    }
    
    //录音系统
    public boolean judgeRecordLevelSend(String level){
    	boolean flag = false;
    	if(level!=null){
    		if(level.equalsIgnoreCase("ALARM")){
    			flag = true;
    		}
    	}
    	return flag;
    }
    
    
    
	public static void main(String[] args) {
		
		//
		/*AlcateLucentTrapReceiver ar = new AlcateLucentTrapReceiver();
		ar.run();*/
		//String message = "1.3.6.1.4.1.637.64.0.10.1.2";
	 	//String[] str =  message.split("\\.");
		//对小数点进行切割
		//String[] strs =  message.split("\\.");
		//System.out.println(SnmpTrapReceiver.getIp("172.20.27.21/46931"));
		//System.out.println(SnmpTrapReceiver.parStr("b3:ac:b3:a4:cd:a8:bb:b0:b8:e6:be:af:28:31:33:29"));
		//SnmpTrapReceiver sr = new SnmpTrapReceiver();
		//sr.run();		
		//System.out.println(SnmpTrapReceiver.changeColorMethod("Maan"));
		//System.out.println(sr.judgeLevelSend("Indeterminate1"));
	}
	
}

代码设计到的配置文件:
snmp.properties

#snmp配置
#本机的IP地址
client_ip=127.0.0.1
#snmp监听端口默认是162
client_port=162
#snmp字符集默认是gbk
snmp_charset=gbk
 
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
单片机发送SNMP协议指令的源代码可以根据具体的单片机型号和开发环境而有所不同。下面是一个基于C语言的示例代码,用于在单片机上发送SNMP协议指令: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> // 定义SNMP协议相关参数 #define SNMP_VERSION 1 #define SNMP_COMMUNITY "public" // 定义OID和命令类型 #define OID_SYS_DESCR "1.3.6.1.2.1.1.1.0" // 系统描述OID #define GET_REQUEST 0x00 // GET请求类型 // 定义SNMP协议数据结构 typedef struct { uint8_t id; uint8_t length; uint8_t type; uint8_t *value; } SnmpPdu; // 函数声明 void sendSnmpPdu(SnmpPdu *pdu); int main() { // 构造SNMP PDU结构体 SnmpPdu pdu; pdu.id = 1; // 任意选择一个标识符 pdu.length = 0; pdu.type = GET_REQUEST; pdu.value = (uint8_t *) OID_SYS_DESCR; // 发送SNMP PDU sendSnmpPdu(&pdu); return 0; } void sendSnmpPdu(SnmpPdu *pdu) { // 构造SNMP协议数据包 // 发送SNMP协议数据包 // 接收SNMP协议应答数据包 // 解析SNMP协议应答数据包 // 处理应答数据 } 在以上代码中,首先定义了SNMP协议的相关参数和OID,以及GET请求类型的命令。然后定义了一个结构体SnmpPdu来表示SNMP协议数据单元,包含了标识符、长度、类型和值。接下来,在主函数中创建了一个SnmpPdu结构体,并初始化了相应的字段。最后调用sendSnmpPdu函数发送SNMP协议数据包。 在sendSnmpPdu函数中,需要根据具体的单片机型号和开发环境,通过相应的库函数来构造和发送SNMP协议数据包,并接收和解析SNMP协议应答数据包。最后,可以对应答数据进行处理,如打印系统描述信息。 总之,上述代码是一个简单的示例,实际上实现SNMP协议的发送需要根据具体的单片机型号和开发环境进行相应的调整和修改。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值