欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

snmp服务器和客户端实现,基于snmp4j snmp 

程序员文章站 2022-07-03 08:41:31
...
snmp协议:简单的网络管理协议,常用于管理网络设备,在java开发中,使用snmp4j作为底层snmp组件比较受欢迎,
下面的例子简单描述了如何基于snmp4j构建简单的snmp服务器和客户端


snmp服务器
package com.gbcom.protocol.snmp;

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.MessageException;
import org.snmp4j.PDU;
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.mp.StateReference;
import org.snmp4j.mp.StatusInformation;
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信息
 * 
 * @author syz
 * 
 * @date 下午3:28:28
 * @version v1.0.0
 * @see SnmpTrapReceiver
 */
public class SnmpTrapReceiver implements CommandResponder {
	private MultiThreadedMessageDispatcher dispatcher;
	private Snmp snmp = null;
	private Address listenAddress;
	private ThreadPool threadPool;

	public SnmpTrapReceiver() {
	}

	//初始化监听。
	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/162")); // 本地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("开始监听Trap信息!");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 实现CommandResponder的processPdu方法, 用于处理传入的请求、PDU等信息 当接收到trap时,会自动进入这个方法
	 * 
	 * @param respEvnt
	 * 
	 */
	public void processPdu(CommandResponderEvent respEvnt) {
		if (respEvnt != null && respEvnt.getPDU() != null) {
			PDU src_pdu = respEvnt.getPDU();
			// 需要确认trap 
			if (src_pdu.getType() == PDU.INFORM) {
				PDU responsePDU = new PDU(src_pdu);
				responsePDU.setErrorIndex(0);
				responsePDU.setErrorStatus(0);
				responsePDU.setType(PDU.RESPONSE);
				StatusInformation statusInfo = new StatusInformation();
				StateReference stateRef = respEvnt.getStateReference();
				try {
					respEvnt.getMessageDispatcher().returnResponsePdu(
							respEvnt.getMessageProcessingModel(),
							respEvnt.getSecurityModel(),
							respEvnt.getSecurityName(),
							respEvnt.getSecurityLevel(), responsePDU,
							respEvnt.getMaxSizeResponsePDU(), stateRef,
							statusInfo);

				} catch (MessageException msgEx) {
					msgEx.printStackTrace();
				}
			}

			Vector<VariableBinding> recVBs = (Vector<VariableBinding>) respEvnt.getPDU()
					.getVariableBindings();
			for (int i = 0; i < recVBs.size(); i++) {
				VariableBinding recVB = recVBs.elementAt(i);
				System.out
						.println(recVB.getOid() + " : " + recVB.getVariable());
			}
		}

	}

	public static void main(String[] args) {
		//开启服务
		SnmpTrapReceiver multithreadedtrapreceiver = new SnmpTrapReceiver();
		multithreadedtrapreceiver.run();
	}

}



snmp客户端
封装常用方法
package com.gbcom.protocol.snmp;

import java.io.IOException;
import java.util.Vector;

import org.apache.log4j.Logger;
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;

/**
 * 本类用于向管理进程发送信息 {@code Trap GET SET}
 * 
 * @author syz
 * @date 下午5:02:20
 * @version v1.0.0
 * @see SnmpSender
 */
public class SnmpSender {
	private static final Logger LOG = Logger.getLogger(SnmpSender.class);
	private Snmp snmp = null;

	private Address targetAddress = null;

	public void initComm() throws IOException {
		// 设置管理进程的IP和端口
		targetAddress = GenericAddress.parse("udp:127.0.0.1/161");
		TransportMapping transport = new DefaultUdpTransportMapping();
		snmp = new Snmp(transport);
		transport.listen();
		LOG.info("init SNMP object succes !!    target = udp:127.0.0.1/161");
	}

	/**
	 * 向管理进程发送Trap报文
	 * 
	 * @throws IOException
	 */
	public void sendTrap() throws IOException { targetAddress = GenericAddress.parse("udp:127.0.0.1/162");
		// 设置 target
		CommunityTarget target = new CommunityTarget();
		target.setAddress(targetAddress);
		// 通信不成功时的重试次数
		target.setRetries(2);
		// 超时时间
		target.setTimeout(1500);
		// snmp版本
		target.setVersion(SnmpConstants.version2c);
		// 创建 PDU
		PDU pdu = new PDU();
		pdu.add(new VariableBinding(new OID(".1.3.6.1.2.3377.10.1.1.1.1"),
				new OctetString("SnmpTrap")));
		pdu.add(new VariableBinding(new OID(".1.3.6.1.2.3377.10.1.1.1.2"),
				new OctetString("JavaEE")));
		pdu.setType(PDU.TRAP);

		// 向Agent发送PDU,并接收Response
		ResponseEvent respEvnt = snmp.send(pdu, target);
		// 解析Response
		readResponse(respEvnt);
//		if (respEvnt != null && respEvnt.getResponse() != null) {
//			Vector<VariableBinding> recVBs = respEvnt.getResponse()
//					.getVariableBindings();
//			for (int i = 0; i < recVBs.size(); i++) {
//				VariableBinding recVB = recVBs.elementAt(i);
//				System.out
//						.println(recVB.getOid() + " : " + recVB.getVariable());
//			}
//		}
	}

	public ResponseEvent sendPDU(PDU pdu) throws IOException {
		// 设置 target
		CommunityTarget target = new CommunityTarget();
		target.setCommunity(new OctetString("public"));
		target.setAddress(targetAddress);
		// 通信不成功时的重试次数
		target.setRetries(1);
		// 超时时间
		target.setTimeout(1500);
		target.setVersion(SnmpConstants.version2c);
		// 向Agent发送PDU,并返回Response
		return snmp.send(pdu, target);
	}

	public void doSet() throws IOException {
		// set PDU
		PDU pdu = new PDU();
		pdu.add(new VariableBinding(new OID(new int[] { 1, 3, 6, 1, 2, 1, 1, 5,
				0 }), new OctetString("SNMPTEST")));
		pdu.setType(PDU.SET);
		readResponse(sendPDU(pdu));
	}

	public void doGet() throws IOException {
		// get PDU
		PDU pdu = new PDU();
		pdu.add(new VariableBinding(new OID(new int[] { 1, 3, 6, 1, 2, 1, 1, 1,
				0 })));
		pdu.add(new VariableBinding(new OID(new int[] { 1, 3, 6, 1, 2, 1, 1, 2,
				0 })));
		pdu.add(new VariableBinding(new OID(new int[] { 1, 3, 6, 1, 2, 1, 1, 3,
				0 })));
		pdu.add(new VariableBinding(new OID(new int[] { 1, 3, 6, 1, 2, 1, 1, 4,
				0 })));
		pdu.add(new VariableBinding(new OID(new int[] { 1, 3, 6, 1, 2, 1, 1, 5,
				0 })));
		pdu.add(new VariableBinding(new OID(new int[] { 1, 3, 6, 1, 2, 1, 1, 6,
				0 })));
		pdu.setType(PDU.GET);
		readResponse(sendPDU(pdu));
	}

	private void readResponse(ResponseEvent respEvnt) {
		// 解析Response
		if (respEvnt != null && respEvnt.getResponse() != null) {
			Vector<VariableBinding> recVBs = (Vector<VariableBinding>) respEvnt.getResponse()
					.getVariableBindings();
			for (int i = 0; i < recVBs.size(); i++) {
				VariableBinding recVB = recVBs.elementAt(i);
				LOG.info("THREAD NUM--"+Thread.currentThread() +  recVB.getOid() + " : " + recVB.getVariable());
			}
		}
	}

	
	
	
	public void doWork(){
		for(int i=0;i<1;i++){
			Thread t  = new Thread(new WorkThread());
			t.start();
		}
	}
	
	class WorkThread implements Runnable{

		@Override
		public void run() {
			while(!Thread.currentThread().interrupted()){
				try {
//					doGet();
//					doSet();
					Thread.sleep(1*1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					LOG.error("THREAD NUM--"+Thread.currentThread() + "InterruptedException",e);
				} catch (Exception e) {
					e.printStackTrace();
					LOG.error("THREAD NUM--"+Thread.currentThread() + "other Exception",e);
					continue;
				} 
			}
				
		}
		
	}
	
	
	public static void main(String[] args) {
		try {
			SnmpSender util = new SnmpSender();
			util.initComm();
//			util.sendTrap();
			LOG.info("---  DO GET --");
//			util.doGet();
			LOG.info("----do set---");
//			util.doSet();
			util.doWork();
			

		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	

}

注意sender的正确运行 需要 开启agent,,一般情况下,设备侧实现snmp agent,服务器实现snmp server


如果需要snmp4j组件作为snmp协议开发,可以参考上面的例子
相关标签: snmp