浏览 5944 次
锁定老帖子 主题:SNMP管理端控制代理端小例子
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-11-01
最后修改:2010-11-01
一个周末一直在进一步研究项目的管理端和代理端通信问题,早上终于有了点眉目,做个笔记。
实验的是一个远程控制代理端关机的功能。
管理端是用Java搭的前台网站,所以使用SNMP4J包编写程序。代理端使用agent++和snmp++两个开发包。
管理端的代码如下:
public static void main(String[] args) { Snmp snmp; try { //设置TransportMapping TransportMapping transport = new DefaultUdpTransportMapping(); snmp = new Snmp(transport); transport.listen(); //设置target CommunityTarget target = new CommunityTarget(); target.setCommunity(new OctetString("public")); target.setAddress(GenericAddress.parse(("10.150.0.84/161")); target.setRetries(2); target.setTimeout(5000); target.setVersion(SnmpConstants.version1); //设置请求PDU PDU requestPDU = new PDU(); requestPDU.setType(PDU.SET);//设置PDU类型 //设置Variable //Gauge32型 无符号长整型 requestPDU.add(new VariableBinding(new OID("1.3.6.1.4.1.502.1.70"), new Gauge32(Integer.valueOf("1")))); //处理返回结果 ResponseEvent respEvnt = snmp.send(requestPDU,target); //向Agent发送PDU,并接收Response PDU responsePDU = respEvnt.getResponse();//解析response if(responsePDU.getErrorIndex() == PDU.noError && responsePDU.getErrorStatus() == PDU.noError) { //如果接收包没有出错 String strResult = responsePDU.getVariableBindings().firstElement().toString(); int len = strResult.indexOf("="); strResult = strResult.substring(len+1, strResult.length()).trim(); if(strResult.equals(value)){ //如果返回值与设置值相同,返回true,否则,返回false System.out.println("set操作成功!"); } else{ System.out.println("set操作失败!oid值与设置值不同!"); } else{ System.out.println("set操作失败,接收包有错误:"+responsePDU.getErrorStatusText()); } snmp.close(); } } catch (Exception e) { e.printStackTrace(); } }
代理端比较复杂,主要代码如下:
//Subagent_Main.h #include "StdAfx.h" #include <windows.h> #include <agent_pp/agent++.h> #include <agent_pp/mib.h> #include <agent_pp/mib_context.h> #include <agentx_pp/agentx_subagent.h> #define GROUP_OID "1.3.6.1.4.1.502.1" //定义oid组 #define SHUTDOWN_OID "1.3.6.1.4.1.502.1.70" //定义关机操作的oid class Subagent_Main : public MibGroup { public: Subagent_Main(const NS_SNMP OctetStr&, SubAgentXMib*); ~Subagent_Main(); }; class Subagent_Shutdown : public MibLeaf { public: Subagent_Shutdown(); virtual ~Subagent_Shutdown(); virtual int set(const Vbx&); };
实现:
//Subagent_Main.cpp #include "stdafx.h" #include "Subagent_Main.h" Subagent_Main::Subagent_Main(const NS_SNMP OctetStr&, SubAgentXMib*) :MibGroup(GROUP_OID, "Subagent") { add(new Subagent_Shutdown()); } Subagent_Main::~Subagent_Main() { } Subagent_Shutdown::Subagent_Shutdown() : MibLeaf(SHUTDOWN_OID, READWRITE, new Gauge32()) { } Subagent_Shutdown::~Subagent_Shutdown() { } Subagent_Shutdown::set(const Vbx& vb) { int isShutdown; vb.get_value(isShutdown); if(isShutdown) { //以下关机代码只对Win2000及以上版本系统有效 HANDLE hToken; TOKEN_PRIVILEGES tkp; if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken)) { AfxMessageBox("无法打开存取命令"); return 1; } LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid); tkp.PrivilegeCount=1; tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken,FALSE,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0); if(GetLastError()!=ERROR_SUCCESS) { AfxMessageBox("无法关机"); return 1; } if(!ExitWindowsEx(EWX_POWEROFF|EWX_FORCE,0)) { AfxMessageBox("无法关机"); return 1; } } return 0; } 测试函数内容如下:
先定义处理的线程函数Subagent:
UINT Subagent(LPVOID pPar) { //AfxMessageBox("子代理线程启动"); SubAgentXMib* mib = new SubAgentXMib(); AgentXSlave* agentx = new AgentXSlave(); AgentXRequestList* reqList = new AgentXRequestList(agentx); // register requestList for outgoing requests mib->set_request_list(reqList); mib->add(new Subagent_Main("", mib)); //初始化 mib->init(); Request* req; while (TRUE) { req = reqList->receive(20000); if (req) { mib->process_request(req); } else { mib->ping_master(); // ping the master } } //AfxMessageBox("子代理线程结束"); delete mib; delete agentx; return 0; }
最后在main函数里加入到开启线程函数即可:
AfxBeginThread(Subagent, NULL); //开启子代理线程监听 运行时,需要代理端装有snmp服务,但不能开启(一直不明白原因)。代理端先开启MasterAgent,再启动我们所写的代理Subagent。这时候管理端即可发控制请求。一运行,代理端即关机。
PS:大致流程如此,中间有很多细节需要慢慢调试。比如snmp++,agent++源码的下载,dll文件的编译生成等等。 下面仅附上SNMP4J开发包。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-11-20
我放弃了 agent++,选用Net-Agent, 同样server端用snmp++ 多线程的api
效果比较好,不过发现两个问题 1 支持中文需要修改ans1源码 2 会把trap id 默认输出到debug |
|
返回顶楼 | |