简单SNMP管理程序的VC++代码实例实现
SNMP(Simple Network Management Protocol)是基于TCP/IP的网络管理协议,关于其工作原理网上很多,百度一下或者看看MSDN,今天在这里记一下实现的步骤,本人工作环境是Windows XP professional SP2 + Microsoft Visual Studio .net 2003,不保证其他平台与本人的步骤一致。
一、安装SNMP服务
先查看系统中是否已经安装有SNMP服务,开始->运行->cmd->回车
输入命令“net start snmp”:
则已经安装有SNMP,如果没有安装,则需先安装SNMP服务:
再按前面的执行“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下的路径差不多,自己找一下。打开窗口之后输入以下命令:
可以发现当前目录下出现一个子目录WIN2000_DEBUG,也可以用nmake删除:
当然现在我们还需要它,根据其readme文件所述,这个示例代码是一个SNMP管理程序(SNMP Manager Application),展示了如何使用WinSNMP的API编写应用程序。它支持SNMP 1的Get,GetNext,Set操作,以及SNMP2的GetBulk操作。而扩展的Walk和Subtree操作则使用GetNext操作来实现。
3. 测试示例
①监听SNMP的端口
②另外打开一个VC.net命令行窗口
③按照其readme里所描述的,在第一个监听窗口会出现以下信息
可惜在本人机器上,第一个窗口始终没有反应,似乎SNMP服务启动时会向局域网发送SNMP的数据包,但我不确定,以后解决了再写。
④再测试几个命令
******************************************************************
三、代码分析
一共三个文件:WSnmpUtil.h WSnmpUtil.Cpp Helper.Cpp
具体代码在后面贴出,这里分析一下其大体结构: 1. WSnmpUtil.h 21个常量定义,一个结构体类型声明,一个GlobalVars类声明,以及19个函数声明。 2. Helper.Cpp
一些函数定义,比如输出提示消息,解析命令行输入的命令,调试信息,地址转换,输出Oid地址以及pSession的参数。
3. WSnmpUtil.Cpp 程序骨干如下:
#i nclude <stdio.h> #i nclude <string.h>
#i nclude <stdlib.h>
#i nclude <winsock2.h>
#i nclude <winsnmp.h>
#i nclude <snmp.h>
#i nclude <mgmtapi.h>
#i nclude "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 补充:
在VC6.0环境下的编译方法: 用nmake没成功,不知道什么原因,错误是: makefile<11> fatal error U1083: target macro '' expands to nothing 不过可以直接用VC编译,步骤如下:
a.新建一个空的控制台工程; b.添加WSnmpUtil.h WSnmpUtil.Cpp Helper.Cpp三个文件;
c.工程->设置->link->对象/库模块;
d.加入user32.lib gdi32.lib snmpapi.lib wsnmp32.lib mgmtapi.lib oldnames.lib Ws2_32.lib; e.去掉SetWindowLongPtr()和GetWindowLongPtr()的Ptr后缀,然后编译。 Windows为了向64位平台转换,在某些API函数后面加上Ptr,参看winuser.h里的定义:
#ifdef _WIN64
LONG_PTR SetWindowLongPtr(
HWND hWnd,
int nIndex,
LONG_PTR dwNewLong
);
#else
#define SetWindowLongPtr SetWindowLong
#endif 本文出自 51CTO.COM技术博客 |



virus
博客统计信息
热门文章
最新评论
友情链接