- 实验要求
- 添加并开启Windows SNMP代理组件;
- 编制控制台程序,接受用户输入的OID字符串,返回在Windows SNMP代理中的对应值;
- 开发GUI界面程序,使用户可通过该程序观察主机CPU、内存、硬盘空间、流量值;
- 开发阈值告警功能,用户通过界面可设置性能阈值(如CPU),当超过阈值时自动报警。
- 实验过程
- 安装并开启Windows SNMP代理组件
安装并开启Windows SNMP组件操作很简单,主要是通过"打开或关闭Windows功能"这个系统工具来完成,具体步骤因操作系统而已。以Windows 7 为例,点击开始菜单的"控制面板",在新窗口左侧选择"程序",在右侧点击"打开或关闭Windows功能",弹出如下图所示的窗口,勾选"简单网络管理协议(SNMP)",包括它的子项"WMI SNMP提供程序",点击"确定",会有几分钟的等待时间。
这样Windows SNMP 服务就已经安装好了,一般而言,这个服务也就启动了。当然,也可以通过Windows服务管理器确认一下相应服务的运行状态,并可以做必要的设置等操作。方法为,按快捷键Win + R,输入"services.msc",打开Windows 服务管理器,如下图。
滚动到SNMP Services,可以看到它的状态是已启动。在左侧窗口中可以停止或重启这个服务。
- 开发SnmpWatcher程序
SnmpWatcher是实现作业要求第2-4项的Windows程序。这套程序的功能本质是一个SNMP Client,对应的SNMP Sever是Windows,具体而言是前文安装和启动的SNMP Service程序。通过阅读相应的RFC文档,实现这样一个C/S模式的客户端,没有什么难度,不过却较为繁琐,好在已经有开发者提供了一套开源的SNMP库——SNMP Sharp Net,官方网站是,开源项目代码托管在Sourceforge,地址是。SnmpWatcher就使用这个库。
下面简单介绍一下SnmpWatcher这个程序的开发。
开发环境和工具如下表。
开发环境和工具 | |
设备 | |
ASUS A41IE 笔记本电脑 | |
软件 | |
操作系统 | Windows 7 Ultimate with SP1, 32 bit(需要安装和开启SNMP服务) |
开发工具 | Microsoft Visual C# 2010 Express |
网络 | |
可以不需要 |
特别说明的是,在这个实验的开发过程中访问的SNMP Server是开发环境的主机,其实也可以是有网络链接的其他主机,不过简单起见,就只用了开发主机了,所以网络可以是不需要的,在实际应用时,SNMP协议必然是运行在网络环境中的。
项目的文件目录如下图所示。现在简单说明一下主要class和namespace的设计。
- Program
这个是应用程序的主类,即包含了Main方法入口。Program类保存了应用程序运行的重要数据作为自己的属性,如SNMP HOST和COMMUNITY,同时负责在启动时读取配置文件"snmpwathcer.ini",这个文件设置了HOST和COMMUNITY数据和用户界面方式命令行或图形窗口,下面是一个"snmpwatcher.ini"的标准模版。
;This is the config file for SnmpWatcher
[SnmpWatcher]
Host=localhost
Community=public
UI=window
- 工具类
即IniFile和SnmpWatcher,IniFile是读取上文提到了"snmpwatcher.ini"配置文件的工具类,主要在Program类中使用。SnmpWatcher是对SnmpSharpNet进行简单封装的工具类,主要在Calc相关类中使用。
- Stat
这个名字空间是主要提供了数据类,即对作业要求监控的CPU、内存、硬盘空间、流量值等的数据的封装,对应的类分别是CpuStat、MemoryStat、DiskStat、NetworkStat。另外一个类Stat是这些类的基类,只作为类型的约束,没有定义属性和实际意义。
各个类的属性和含义,如下表。
数据类属性说明 | ||
CpuStat | ||
CoreNum:uint | CPU内核数 | |
Loads:List<uint> | CPU负载数列 | |
LoadRate:double | CPU负载率(负载和/100) | |
MemoryStat | ||
Size:uint | 内存总空间 | |
UsedSize:uint | 内存使用空间 | |
UsedRate:double | 内存使用率 | |
DiskStat | ||
Size:uint | 磁盘总空间 | |
UsedSize:uint | 磁盘使用空间 | |
UsedRate:double | 磁盘使用率 | |
NetworkStat | ||
InBytes:uint | 流进字节数 | |
OutBytes:uint | 流出字节数 |
- Clac类
这个名字空间这个名字空间下有1个接口和4个类,用于和Host通信,提交含有OID的SNMP请求,读取SNMP响应报文并作解析,获得系统的CPU、内存、硬盘、网络状态数据信息,存储到对应的Stat类中。
接口是ICalc,接口定义如下。
interface ICalc<T> where T : Stat
{
T CalcStat();
}
其余4个类实现了这个接口,四个类分别实现的功能和使用到的OID如下表所示。
Calc类 | 功能 | 使用到的OID | 含义 |
CpuCalc | 查询CPU状态数据,存储在CpuStat对象中 | .1.3.6.1.2.1.25.3.3.1.2 | 遍历各个CPU的内核的负载 |
MemoryCalc | 查询内存状态数据,存储在MemoryStat对象中 | 1.3.6.1.2.1.25.2.3.1.2 | 存储单元类型 |
1.3.6.1.2.1.25.2.3.1.4 | 存储单元大小 | ||
1.3.6.1.2.1.25.2.3.1.5 | 总存储单元数 | ||
1.3.6.1.2.1.25.2.3.1.6 | 使用存储单元数 | ||
1.3.6.1.2.1.25.2.1.2 | 内存存储单元类型码 | ||
DiskCalc | 查询硬盘状态数据,存储在DiskStat对象中 | 1.3.6.1.2.1.25.2.3.1.2 | 存储单元类型 |
1.3.6.1.2.1.25.2.3.1.4 | 存储单元大小 | ||
1.3.6.1.2.1.25.2.3.1.5 | 总存储单元数 | ||
1.3.6.1.2.1.25.2.3.1.6 | 使用存储单元数 | ||
1.3.6.1.2.1.25.2.1.4 | 硬盘存储单元类型码 | ||
NetworkCalc | 查询硬盘状态数据,存储在NetwrokStat对象中 | 1.3.6.1.2.1.2.2.1.6 | 物理地址 |
1.3.6.1.2.1.2.2.1.10 | 输入字节数 | ||
1.3.6.1.2.1.2.2.1.16 | 输出字节数 |
需要说明的是,在1.3.6.1.2.1.25.2下内存和硬盘被抽象成同一种存储设备,通过1.3.6.1.2.1.25.2.3.1.2这个值进行类别判断。这个过程相对比较复杂,具体解析过程,还是请查阅源代码。
- UI
这个名字空间提供了两套用户接口,一个是命令行的(Console1),另一个是图形窗口的(Form1),另外的两个类Form1Settings是对Form1数据的抽象,主要是Form1的刷新时间和CPU、内存、磁盘的告警阈值,Form1SettingsDialog是修改阈值的窗口类,Form1Settings在Form1SettingsDialog和Form1间传递。
Console1,实现的功能比较简单,主要是完成了作业的第2个要求,即通过输入OID查询系统状态信息,另外提供了一个命令打开图像窗口,使用演示如下图所示。
Form1实现了作业的另两个要求,使用演示如下图。
这个窗口显示监视主机的状态信息,可以验证和当前主机的实际信息是一致的,除了CPU会有些误差,这个误差出现的原因,我还在思考中。
点击Settings进入设置对话框。把Memory Threshold设为50以后点OK,返回主界面,这时等待刷新,然后可以看到状态栏出现了"WARNING"的红色警告。
- 附:SnmpWatcher程序源代码
我把SnmpWatcher的源代码放到了Bitbucket上,可以通过hg下载全部源代码,命令如下:
hg clone
当然也可以在Bitbucket上在线查看,地址是: