SNMP(简单网络管理协议): 专门用于在 IP 网络管理网络节点(服务器、工作站、路由器、交换机及HUBS等)的一种标准协议,它是一种应用层协议。 SNMP 使网络管理员能够管理网络效能,发现并解决网络问题以及规划网络增长。通过 SNMP 接收随机消息(及事件报告)网络管理系统获知网络出现问题。
SNMP的前身是简单网关监控协议(SGMP),用来对通信线路进行管理。随后,人们对SGMP进行了很大的修改,特别是加入了符合Internet定义的SMI和MIB,改进后的协议就是著名的SNMP。

一个SNMP管理的网络由下列三个关键组件组成:
主代理是一个在可运行的SNMP网络组件上运作的软件,可回应从管理站发出的SNMP要求。它的角色类似C/S术语中的服务器。主代理依赖子代理提供有关特定功能的管理信息。
子代理是一个在可运行的SNMP网络组件上运作的软件,运行在特定子系统的特定管理信息库(MIB,Management Information Base)中定义的信息和管理功能。子代理的一些能力有:搜集主代理的信息、配置主代理的参数、回应管理者的要求、产生警告或陷阱trap
主代理和子代理的角色可以合并,在这种情况下我们可以简单的称之为代理(agent)。
SNMP定义了五种Manager与Agent之间的通讯形式。

前三项都是属于Manager向Agent发出的讯息,后两项则属于Agent向Manager发出的讯息
Trap:当设备发生了各种事件之后,产生的MIB信息由SNMP代理主动向NMS发送,是不需要NMS请求的,NMS收到之后不需要向SNMP代理发送确认消息,SNMP发出去的Trap是根本不知道NMS是否收到,自己发送完毕之后,这些MIB信息会马上删除,不会驻留内存里面。
informs:informs和Trap恰好相反、设备发生事件后,这些信息并不会主动向NMS通告,除非NMS发送requst来查询,然后才会发出去,但是发出去的informs之后会保留在内存里面,当NMS收到informs之后必须向SNMP代理发送确认消息,如果不发送确认消息,SNMP代理会重复多次发送informs(informs具有可靠性)
通过NMS来更改设备上的配置,查询设备信息,发送的数据包为Get,更改设备的配置为Set
SNMP是管理进程(NMS)和代理进程(Agent)之间的通信协议。它规定了在网络环境中对设备进行监视和管理的标准化管理框架、通信的公共语言、相应的安全和访问控制机制。网络管理员使用SNMP功能可以查询设备信息、修改设备的参数值、监控设备状态、自动发现网络故障、生成报告等。
SNMP具有以下技术优点:
先看一下SNMP协议要传输的内容:SNMP的5种协议数据单元_协议分析网
接下来就是用SNMP4J协议的jar包来完成各个功能:http://www.snmp4j.org/html/download.html
SNMP4J把开发包分为了两个,一个SNMP4J.jar主要负责get,trap,set,一个是SNMP4J-Agent.jar主要负责作为一个网元被管理。
需要用到两个配置文件bc和cfg文件,可以在这里下载:http://download.csdn.net/detail/three_man/7477991
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.snmp4j.agent.BaseAgent;
import org.snmp4j.agent.CommandProcessor;
import org.snmp4j.agent.DuplicateRegistrationException;
import org.snmp4j.agent.io.ImportModes;
import org.snmp4j.agent.mo.DefaultMOTable;
import org.snmp4j.agent.mo.MOTableRow;
import org.snmp4j.agent.mo.snmp.RowStatus;
import org.snmp4j.agent.mo.snmp.SnmpCommunityMIB;
import org.snmp4j.agent.mo.snmp.SnmpNotificationMIB;
import org.snmp4j.agent.mo.snmp.SnmpTargetMIB;
import org.snmp4j.agent.mo.snmp.StorageType;
import org.snmp4j.agent.mo.snmp.VacmMIB;
import org.snmp4j.agent.security.MutableVACM;
import org.snmp4j.mp.MPv3;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityModel;
import org.snmp4j.security.USM;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.Variable;
public class MyAgent extends BaseAgent {
private List<DefaultMOTable> moTables = new ArrayList<DefaultMOTable>();
private String community;
protected MyAgent(File bootCounterFile, File configFile, List<DefaultMOTable> moTables, String community) {
super(bootCounterFile, configFile, new CommandProcessor(new OctetString(MPv3.createLocalEngineID())));
this.moTables = moTables;
this.community = community;
}
@Override
protected void registerManagedObjects() {
try {
for (DefaultMOTable table : moTables) {
server.register(table, null);
}
} catch (DuplicateRegistrationException e) {
e.printStackTrace();
}
}
public void startUp(){
try {
this.init();
} catch (IOException e) {
e.printStackTrace();
}
this.loadConfig(ImportModes.REPLACE_CREATE);
this.addShutdownHook();
this.getServer().addContext(new OctetString(community));
this.finishInit();
this.run();
this.sendColdStartNotification();
}
/**
* to set community
*/
@Override
protected void addCommunities(SnmpCommunityMIB communityMIB) {
Variable[] com2sec = new Variable[] {
new OctetString(community), // community name
new OctetString("cpublic"), // security name
getAgent().getContextEngineID(), // local engine ID
new OctetString(community), // default context name
new OctetString(), // transport tag
new Integer32(StorageType.nonVolatile), // storage type
new Integer32(RowStatus.active) // row status
};
MOTableRow row =
communityMIB.getSnmpCommunityEntry().createRow(
new OctetString("public2public").toSubIndex(true), com2sec);
communityMIB.getSnmpCommunityEntry().addRow(row);
}
}
import java.io.IOException;
import java.util.logging.Logger;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;
import com.prince.snmp.tool.Command;
import com.prince.snmp.tool.util.Configure;
import com.prince.snmp.tool.util.Const;
/**
* 构建一个多线程的Trap Receiver
* @author wangzijian
*
*/
public class SnmpReceiver implements Command{
private final Logger log = Logger.getLogger(SnmpReceiver.class.getName());
@Override
public void startUp() throws IOException {
log.info("Snmp Trap Receiver Start");
log.info("listened on " + Configure.getInstance().getUdpTrapIpPort());
ThreadPool pool = ThreadPool.create(Const.THREAD_POOL_NAME, Const.AGENT_THREAD_NUM);
MultiThreadedMessageDispatcher dispatcher = new MultiThreadedMessageDispatcher(pool, new MessageDispatcherImpl());
Address listenAddress = GenericAddress.parse(Configure.getInstance().getUdpTrapIpPort());
TransportMapping transport = new DefaultUdpTransportMapping((UdpAddress) listenAddress);
// 构建SNMP,并且使其开始监听
Snmp snmp = new Snmp(dispatcher, transport);
snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());
snmp.listen();
snmp.addCommandResponder(new CommandResponderImpl());
}
}
package com.prince.snmp.tool.receiver;
import java.util.List;
import java.util.logging.Logger;
import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.PDU;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.VariableBinding;
public class CommandResponderImpl implements CommandResponder {
private final Logger log = Logger.getLogger(CommandResponderImpl.class.getName());
@Override
public void processPdu(CommandResponderEvent event) {
PDU pdu = event.getPDU();
if(PDU.TRAP == pdu.getType()){
operate(pdu);
}else{
log.info("pdu method is:" + pdu.getType() + " not a trap");
}
}
private void operate(PDU pdu) {
List<VariableBinding> bindings = pdu.getBindingList(new OID(".1"));
for (VariableBinding binding : bindings) {
System.out.println(binding.getOid() + "====" + binding.getVariable().toString());
}
}
}
package com.prince.snmp.tool.trap;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Vector;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import com.prince.snmp.tool.Command;
import com.prince.snmp.tool.trap.dataGenerator.ITrapGenerator;
import com.prince.snmp.tool.util.Configure;
public class TrapSender implements Command{
private Snmp snmp;
private Address targetAddress;
private ITrapGenerator generator;
public TrapSender(ITrapGenerator generator) {
this.generator = generator;
targetAddress = GenericAddress.parse(Configure.getInstance().getUdpTrapIpPort());
TransportMapping<UdpAddress> transport = null;
try {
transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
transport.listen();
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendTrap(){
CommunityTarget target = new CommunityTarget();
target.setAddress(targetAddress);
target.setRetries(Configure.getInstance().getRetries());
target.setTimeout(Configure.getInstance().getTimeOut());
target.setCommunity(new OctetString(Configure.getInstance().getCommunity()));
target.setVersion(Configure.getInstance().getSnmpVersion());
List<TrapData> datas = generator.generateTrapData();
try {
for (TrapData trapData : datas) {
sendPdu(trapData, target);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void sendPdu(TrapData trapData, CommunityTarget target) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, IOException {
PDU pdu = MoToPdu.moToPdu(trapData);
ResponseEvent respEvnt = snmp.send(pdu, target);
// 解析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);
System.out.println(recVB.getOid() + " : " + recVB.getVariable());
}
}
}
}
pdu.add(new VariableBinding(SnmpConstants.sysUpTime, new TimeTicks(trap.getSysUpTime())));
pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID(trap.getTrapOid())))
private static void simpleGet() throws IOException {
TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(transport);
transport.listen();
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString("CONV"));
Address targetAddress = GenericAddress.parse("udp:10.141.43.237/161");
target.setAddress(targetAddress);
target.setRetries(3);
target.setTimeout(3000);
target.setVersion(SnmpConstants.version2c);
PDU pdu = new PDU();
pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.7569.1.2.1.23.3.1")));
pdu.setType(PDU.GETBULK);
pdu.setMaxRepetitions(20);
pdu.setNonRepeaters(0);
ResponseEvent respEvnt = snmp.send(pdu, target);
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);
System.out.println(recVB.getOid() + " : " + recVB.getVariable());
}
}
}
具体的代码没有写,因为下一篇会共享一个小的工具,可以以配置文件为基础来构建Receiver,发送Trap,构建Agent等。
具体参考:阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台
简单网络管理协议SNMP(史上最全)_奇妙之二进制的博客-CSDN博客_snmp是什么协议
我正在使用i18n从头开始构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在rubyonrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi
有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url
我安装了ruby版本管理器,并将RVM安装的ruby实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby。有没有办法让emacs像shell一样尊重ruby的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。
是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s
我的工作要求我为某些测试自动生成电子邮件。我一直在四处寻找,但未能找到可以快速实现的合理解决方案。它需要在outlook而不是其他邮件服务器中,因为我们有一些奇怪的身份验证规则,我们需要保存草稿而不是仅仅发送邮件的选项。显然win32ole可以做到这一点,但我找不到任何相当简单的例子。 最佳答案 假设存储了Outlook凭据并且您设置为自动登录到Outlook,WIN32OLE可以很好地完成此操作:require'win32ole'outlook=WIN32OLE.new('Outlook.Application')message=
网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识
//1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json
在前面两节的例子中,主界面窗口的尺寸和标签控件显示的矩形区域等,都是用C++代码编写的。窗口和控件的尺寸都是预估的,控件如果多起来,那就不好估计每个控件合适的位置和大小了。用C++代码编写图形界面的问题就是不直观,因此Qt项目开发了专门的可视化图形界面编辑器——QtDesigner(Qt设计师)。通过QtDesigner就可以很方便地创建图形界面文件*.ui,然后将ui文件应用到源代码里面,做到“所见即所得”,大大方便了图形界面的设计。本节就演示一下QtDesigner的简单使用,学习拖拽控件和设置控件属性,并将ui文件应用到Qt程序代码里。使用QtDesigner设计界面在开始菜单中找到「Q