113E博章

       登录 /注册
首页 一算子网 发布
分类 :c++/vc

简单SNMP管理程序的VC+代码实例实现

[ 2007-6-10 23:56:00 | 发表者 : zihe ]

  友情提醒:

  snmp(simple network management protocol)是基于tcp/ip的网络管理协议,关于其工作原理网上很多,百度一下或者看看msdn,今天在这里记一下实现的步骤,本人工作环境是windows xp professional sp2 + microsoft visual studio .net 2003,不保证其他平台与本人的步骤一致。

  一、安装snmp服务

  先查看系统中是否已经安装有snmp服务,开始->运行->cmd->回车

  输入命令“net start snmp”:

c:\documents and settings\mmpire>net start snmp

snmp service 服务正在启动 .

snmp service 服务已经启动成功。

c:\documents and settings\mmpire>

  则已经安装有snmp,如果没有安装,则需先安装snmp服务:

  1. 打开控制面板,双击[添加/删除程序];

  2. 在弹出的[添加/删除程序]对话框的左窗格中,单击 [添加/删除 windows 组件];

  3. 在弹出的[windows 组件向导]中双击 [管理和监视工具]。

  4. 在弹出的[管理和监视工具] 对话框中,勾选[简单网络管理协议],单击 [确定]。

  5. 安装协议时需要用到windows xp sp2安装盘,之后可能需要重启,不过我的机器没要求:p

  再按前面的执行“net start snmp”命令启动snmp服务。

******************************************************************

  二、代码示例

  这种编程一般都有套路,即需要遵循一定的格式,ms提供了snmp编程的样例代码,这个样例是一个最简单的snmp管理程序,用户通过输入snmp命令来进行交互。我们可以从中查看winsnmp的api的使用方法。所有样例代码都在platform sdk中,可以在下面的地址下载到最新版的platform sdk:
http://www.microsoft.com/downloads/details.aspx?familyid=484269e2-3b89-47e3-8eb7-1f2be6d7123a&displaylang=en

  可以看看它的介绍(哈,几乎支持了所有现在的windows版本),只要下载全部17个psdk-full.*.cab及最后一个psdk-full.exe,之后全部解压缩并安装到某个文件夹中即可。

  1. 找到示例代码

  进入platformsdk\samples\netds\snmp,可以看到三个文件夹:snmputil,testdll,wsnmp以及一个makefile。其中snmputil与testdll是基于nt平台的,略去不说,具体参看内附的readme。而makefile是用来编译所有这三个文件里的模块的,对于xp平台前两个文件夹里的模块不能正确编译,所以也不看。进入wsnmp文件夹,我们需要的示例代码就在这里。将五个文件全拷贝到d盘根目录。

  2. 编译示例代码

  从以下路径打开vc.net命令行窗口:

  开始->所有程序-> visual studio .net 2003->visual studio .net 2003 命令提示。

  vc6下的路径差不多,自己找一下。打开窗口之后输入以下命令:

c:\documents and settings\mmpire>d:

d:\>nmake all

microsoft (r) 程序维护实用工具 7.10.3077 版

版权所有 (c) microsoft corporation。保留所有权利。

if not exist "win2000_debug/" mkdir win2000_debug cl -zi -od -ddebug -c -dcrtapi1=_cdecl -dcrtapi2=_cdecl -nologo -d_x86_=1-dwin32 -d_win32 -w3 -d_winnt -d_win32_winnt=0x0500 -d_win32_ie=0x0500 –dwinv er=0x0500 -d_mt -mtd /fo"win2000_debug\\" /fd"win2000_debug\\" wsnmputil.cpp wsnmputil.cpp cl -zi -od -ddebug -c -dcrtapi1=_cdecl -dcrtapi2=_cdecl -nologo -d_x86_=1 -dwin32 -d_win32 -w3 -d_winnt -d_win32_winnt=0x0500 -d_win32_ie=0x0500 –dwinv er=0x0500 -d_mt -mtd /fo"win2000_debug\\" /fd"win2000_debug\\" helper.cpp helper.cpp link /debug:full /debugtype:cv /incremental:no /nologo -subsystem:conso le,5.0 kernel32.lib ws2_32.lib mswsock.lib advapi32.lib -out:win2000_debug\wsnm putil.exe win2000_debug\wsnmputil.obj win2000_debug\helper.obj user32.lib gdi32.lib snmpapi.lib wsnmp32.lib mgmtapi.lib oldnames.lib

d:\>

  可以发现当前目录下出现一个子目录win2000_debug,也可以用nmake删除:

d:\>nmake clean

microsoft (r) 程序维护实用工具 7.10.3077 版

版权所有 (c) microsoft corporation。保留所有权利。

if exist win2000_debug/ rd /s /q win2000_debug

d:\>

  当然现在我们还需要它,根据其readme文件所述,这个示例代码是一个snmp管理程序(snmp manager application),展示了如何使用winsnmp的api编写应用程序。它支持snmp 1的get,getnext,set操作,以及snmp2的getbulk操作。而扩展的walk和subtree操作则使用getnext操作来实现。

  3. 测试示例

  ①监听snmp的端口

d:\>cd win2000_debug

d:\win2000_debug>wsnmputil trap

wsnmputil: listening for traps...


  ②另外打开一个vc.net命令行窗口

d:\win2000_debug>net stop snmp

snmp service 服务正在停止..

snmp service 服务已成功停止。

d:\win2000_debug>net start snmp

snmp service 服务正在启动 .

snmp service 服务已经启动成功。

d:\win2000_debug>

  ③按照其readme里所描述的,在第一个监听窗口会出现以下信息

d:\win2000_debug>wsnmputil trap

wsnmputil: listening for traps...

agent : 127.0.0.1

oid :1.3.6.1.2.1.1.3.0

oid string: system.sysuptime.0

timeticks: 0

(注:…太长…略去)

  可惜在本人机器上,第一个窗口始终没有反应,似乎snmp服务启动时会向局域网发送snmp的数据包,但我不确定,以后解决了再写。

  ④再测试几个命令

d:\win2000_debug>wsnmputil

usage: wsnmputil [-v1|-v2] [get|getnext|walk|getbulk|subtree] agent community [

non_repeaters max_repetitions] oid [oid ...]

examples:

wsnmputil trap

wsnmputil -v1 get localhost public 1.3.6.1.2.1.1.1.0

wsnmputil -v1 getnext localhost public 1.3.6.1.2.1.1.1.0

wsnmputil -v1 subtree localhost public 1.3.6.1.2.1.1

wsnmputil -v1 set toaster public 1.3.6.1.4.1.12.2.5.0 2

wsnmputil -v2 walk localhost public 1

wsnmputil -v2 getbulk toaster public 1 2 1.3.6.1.2.1.1.2.0 1.3.6.1.2.1.4.2

2.1.2 1.3.6.1.2.1.4.22.1.4

d:\win2000_debug>wsnmputil -v2 walk localhost public 1

(注:….非常多的结果…不过现在还不知道什么意思…汗)

d:\win2000_debug>wsnmputil -v1 get localhost public 1

oid :1.3.6.1.2.1.1

system

null – null

d:\win2000_debug>wsnmputil -v1 getnext localhost public 1.3.6.1.2.1.1.1.0

(注: 1.3.6.1.2.1.1.1.0是在oidview里看到的,貌似是本人agent的地址)

oid :1.3.6.1.2.1.1.2.0

system.sysobjectid.0

object identifier - .1.3.6.1.4.1.311.1.1.3.1.1
******************************************************************

  三、代码分析

  一共三个文件:wsnmputil.h wsnmputil.cpp helper.cpp,具体代码在后面贴出,这里分析一下其大体结构:

  1. wsnmputil.h

  21个常量定义,一个结构体类型声明,一个globalvars类声明,以及19个函数声明。

  2. helper.cpp

  一些函数定义,比如输出提示消息,解析命令行输入的命令,调试信息,地址转换,输出oid地址以及psession的参数。

  3. wsnmputil.cpp

  程序骨干如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <winsock2.h>
#include <winsnmp.h>
#include <snmp.h>
#include <mgmtapi.h>
#include "wsnmputil.h"
//外部全局变量gvars,记录用户命令等信息

globalvars gvars;

int main( int argc, char **argv )
{ //初试化一般参数
 psnmp_mgr_session psession = null;
 int nreturn = 0;
 bool result;
 int i = 0;

 //初试化snmp参数

 smiuint32 nmajorversion = 0;
 smiuint32 nminorversion = 0;
 smiuint32 nlevel = 0;
 smiuint32 ntranslatemode = 0;
 smiuint32 nretransmitmode = 0;

 //接收用户在命令行输入的命令,主要记录在变量gvars中

 parsecommandline( argc, argv );

 //加载snmp服务

 snmpstartup(&nmajorversion,&nminorversion,&nlevel,&ntranslatemode,&nretransmitmode);

 //分两种情况设置传输模式(snmp1/snmp2)

 if ( gvars.version == false )
  snmpsettranslatemode( snmpapi_untranslated_v1 );
 else
  snmpsettranslatemode( snmpapi_untranslated_v2 );
 //为会话分配内存空间
 psession = ( psnmp_mgr_session )snmputilmemalloc( sizeof( snmp_mgr_session ) );

 /*创建一个隐藏的负责监听winsnmp消息的窗口,这是一段典型的调用createwindow()创建windows窗口的代码。(注:窗口处理函数是notificationwndproc(),本程序调用creatwindow()后返回,而由系统来创建窗口,其中就要调用这个窗口处理函数,这种由程序员编写而由系统调用的函数需要定义为callback函数)注意:snmp接收的数据包(pdu)就在窗口进程里处理*/

 createnotificationwindow( psession );
 //建立会话
 snmpopen( psession->hwnd, wm_snmp_incoming );
 //解析用户在命令行输入的命令
 switch (gvars.operation)
 {
  case trap:waitfortraps( psession );break;
  case walk:createpdusendrequest( psession, null );break;
  case get:
  case get_next:result = createpdusendrequest( psession, null ); break;
   //创建一个pdu并发送一个请求
  case get_bulk:result = createpdusendrequest( psession, null ); break;
  case sub_tree:result = createpdusendrequest( psession, null ); break;
  case set:result = createpdusendrequest( psession, null );break;
  //先探测所给agent是否存在,之后再发送设定消息
 }

 closewinsnmpsession ( psession );//关闭winsnmp任务,调用了snmpclose()
 snmputilmemfree( psession );//释放内存
 snmpcleanup( );//清理工作
 wsacleanup( );//关闭windows sockets
 return ( nreturn );
} //end of main()

  四、其他说明

  1. 用vc编译

  方法一:

  建立工程并添加上述三个文件,这时可以编译通过,但链接是会出现许多错误,大多是“未能解析的符号”,这时我们还需要给工程添加一些库,操作路径如下:

  项目->属性->链接器->命令行

  在“附加选项”中加入

"user32.lib gdi32.lib snmpapi.lib wsnmp32.lib mgmtapi.lib oldnames.lib ws2_32.lib"

  前面的lib库摘自其makefile,最后一个ws2_32.lib是google出来的:p

  方法二:

  打开vc.net,按以下操作路径:

  文件->新建->项目->vc++项目->常规->生成文件项目->起个名字->确定->应用程序设置->在生成命令行里输入nmake->完成

  然后把那三个文件及makefile拷贝到这个项目的目录下面,就可以编译了:

  生成->生成解决方案

  方法三:

  前面说过了,打开vc的命令行窗口直接用nmake命令:p
上一篇:VC+编程实现对火焰的计算机动态仿真   
下一篇:用C+实现跨平台游戏开发之Allegro引擎

浏览模式 : 显示全部 | 评论 : 0 | 排序 | 浏览 : 196

我要发表文章
回复标题:  
    Email :
* 请输入验证码
 
统计数据
文章数量 : 300217
评论次数 : 370
访问次数 : 15582805
在线人数 : 2171

附近文章
  • 英国投票否决C+/CLI 微软...
  • C+内存对象大会战
  • 在VC+应用程序中实现颜色...
  • C+箴言:确保公开继承模拟...
  • VC+编程实现对火焰的计算...
  • 用C+实现跨平台游戏开发之...
  • C+箴言:避免覆盖通过继承...
  • 用C+实现跨平台游戏开发之...
  • C+程序中导出Word文档的简...
  • C+面向对象程序设计的重要...
热门文章
  • 如...
  • Socket编程中select()的妙...
  • 如何在DLL中创建窗体(对话...
  • 重载赋值运算符 C+/VC
  • 展现TRACE之威力 C+/VC
  • ·用豪杰大眼睛制作照片v...
  • 一個簡單的錄音放音程序 ...
  • 用Socket接口实现网络异步...
  • MFC动态创建控件的消息处...
  • 实现服务器端的多线程SOC...
最新文章
  • 电视剧上门女婿剧情 介绍
  • 电视剧东方朔 介绍
  • 在易界个中神位的作用
  • 神煞往亡的解释
  • 第十五课 混合模式应用范...
最近评论
  • 匿名
  • 匿名
  • 匿名
  • 匿名
  • 来了个,我要呀!
  • 匿名
  • 匿名
  • 匿名
  • 匿名
  • zzq424
 
 

Copyright (C) 一算子网 2006-2008, All Rights Reserved 京ICP备06020154号
服务QQ: 有问题请留言 留言邮箱pinhu530@sohu.com