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

2016-02-19 19:06 3 1 收藏

人生本是一个不断学习的过程,在这个过程中,图老师就是你们的好帮手,下面分享的简单SNMP管理程序的VC++代码实例实现懂设计的网友们快点来了解吧!

【 tulaoshi.com - 编程语言 】

  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 Settingsmmpirenet start snmp

SNMP Service 服务正在启动 .

SNMP Service 服务已经启动成功。

C:Documents and Settingsmmpire

  则已经安装有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. 找到示例代码

  进入platformsdkSamplesNetDSSnmp,可以看到三个文件夹: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 Settingsmmpired:

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_DEBUGwsnm putil.exe WIN2000_DEBUGwsnmputil.obj WIN2000_DEBUGhelper.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_DEBUGwsnmputil trap

WSnmpUtil: listening for traps...

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

D:WIN2000_DEBUGnet stop snmp

SNMP Service 服务正在停止..

SNMP Service 服务已成功停止。

D:WIN2000_DEBUGnet start snmp

SNMP Service 服务正在启动 .

SNMP Service 服务已经启动成功。

D:WIN2000_DEBUG

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

D:WIN2000_DEBUGwsnmputil 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的数据包,但我不确定,以后解决了再写。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  ④再测试几个命令

D:WIN2000_DEBUGwsnmputil

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_DEBUGwsnmputil -v2 walk localhost public 1

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

D:WIN2000_DEBUGwsnmputil -v1 get localhost public 1

OID :1.3.6.1.2.1.1

system

NULL – NULL

D:WIN2000_DEBUGwsnmputil -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"

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

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

  方法二:

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

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

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

  生成-生成解决方案

  方法三:

  前面说过了,打开VC的命令行窗口直接用nmake命令:P

来源:https://www.tulaoshi.com/n/20160219/1620018.html

延伸阅读
标签: PHP
  图书查询部分: <? if(!$UploadAction): ? <? //本程序是为输出书名,作者、出版社资料而设。 //编者:孔秀祥。日期:2001/3/25 ? <HTML<HEAD <TITLE书目查询 </TITLE </HEAD <BODY<TABLE align=CENTER <FORM ENCTYPE= "multipart/form-data" NAME = "SubmitForm" ACTI...
标签: PHP
  本级程序所用的数据表结构: # -------------------------------------------------------- # # 数据表的结构 'author' # CREATE TABLE author (    author_id int(6) DEFAULT '0' NOT NULL auto_increment,    first_name varchar(20) binary NOT NULL,    last_name varchar(2...
导读: 摘要: 本文主要介绍了多任务管理中的多进程管理技术,对进程的互斥运行、子进程的创建与结束等作了较详细的阐述。 关键词: VC++6.0;进程;环境变量;子进程 进程 进程是当前操作系统下一个被加载到内存的、正在运行的应用程序的实例。每一个进程都是由内核对象和地址空间所组成的,内核对象可以让系统在其内...
滑动控件是Windows中最常用的控件之一。一般而言它是由一个滑动条,一个滑块和可选的刻度组成,用户可以通过移动滑块在相应的控件中显示对应的值。通常,在滑动控件附近一定有标签控件或编辑框控件,用于显示相应的值。滑动控件在应用程序中用途级为广泛,如在桌面的属性中就可以看到。为此,让我们一起来看一下它的实现方法。 (...
标签: PHP
  图书目录输入部分: <? if(!$UploadAction): ? <? //本程序是为输入书名,作者、出版社资料而设。 //编者:孔秀祥。日期:2001/3/24 /* session_start(); if (!isset($auth_passed)) { echo "本功能只有授权用户才能使用。"; return -1; } if(isset($u_name)) {   session_name($u_name); /...

经验教程

365

收藏

69
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部