命令行工具: 在远程代理上执行SNMP操作,如SNMP GET、SNMP GETNEXT、SNMP SET、SNMP BULK和SNMP WALK。
在设计过程中,我们使用了其一系列高层components和UI Beans,如SnmpTarget、SnmpTable等,
其高层API的层次结构如下所示:
图1-6 Overview of High-Level API
(关于具体的Adventnet SNMP API介绍及API的具体结构层次与使用方法请参见其Documentation)
三,功能实现及结果展示
1,开发环境及辅助工具的安装与配置
(1),JDK的安装与配置
程序设计实现采用Java语言,开发工具为JDK1.5.10,此工具可以在Http://java.sun.com免费下载,下载后运行即可安装。安装完后需要设置环境变量。在我的电脑->高级->环境变量 中选择“Path”变量,在前面加入“%JDK_Home%/bin”,其中“%JDK_Home%”表示用户的JDK安装目录,而ClassPath变量在1.5.10版的JDK下实际上是可以不用配置的。
(2),AdventNet SNMP API 4的安装与配置。
程序设计采用了AdventNet的SNMP API开发工具包,此工具可以在Http://www.adventnet.com.cn免费下载,下载后运行即可安装,安装完后需要设置ClassPath环境变量,在其中加入
.; %AdventNet API_Home%\jars\AdventNetLogging.jar; %AdventNet API_Home%\jars\AdventNetSnmp.jar; %AdventNet API_Home%\jars\ JimiProClasses.zip
其中,“.”代表当前目录,%AdventNet API_Home%表示AdventNet SNMP API 4的安装目录。这些类包都是我在程序设计中要用到的。
(3),SNMP代理服务的安装
在程序试验及调试过程中,我们需要有SNMP代理进程来检验程序是否设计正确、能否得到正确结果,由于条件有限,我只有在自己的及局域网内的其它PC机上安装了Windows系统光盘附带的SNMP简单网络管理协议组件。
安装过程为:
在控制面板中打开“添加和删除程序”,选择“添加和删除Windows组件”,选择“管理和监视工具”,点击“详细信息”,勾选“简单网络管理协议”,依次点击确定,插入光盘即可完成安装。安装完成后,需要开启SNMP服务才能生效。在控制面板中打开“管理工具”,打开“服务”,将“SNMP Service”服务项开启即可。
2,程序设计及结果展示
本设计的难点在于协议的理解及开发工具包AdventNet Snmp Api的使用,程序设计实现较为简单,只有一个源代码文件:MibExplorer.java,代码量400行左右。程序运行主界面如图3-1所示:
图3-1程序运行主界面
(注:界面左侧为装载了的MIB模型的JPanel,右侧的一系列JTextField接收一系列参数,按钮执行一系列操作,中间的JTextArea显示Get,GetNext及Set的操作结果,Clear清空结果,右下的JTextArea显示Mib对象的描述信息。“File”菜单里的“Save Result As...”项允许将执行结果保存到外存)
程序有四个主要操作实现四个主要功能:Get,GetNext,GetTable,Set
² Get和GetNext: 用于读取设备MIB信息库中实例对象的单个值,Get取OID表示的对象实例当前值,GetNext则是取下一值。循环利用GetNext操作可遍历MIB中的对象。
² GetTable: 用于读取设备MIB信息库中以表的形式存储的对象实例。
² Set: 用于简单的设置MIB中可读写的对象实例的值。
程序的其它部分为界面的设计(采用GridBagLayout+GridLayout等布局管理器),MIBTree的处理,以及一些附加的功能(如保存结果到文件,MIB对象的描述显示等)。
主要功能的执行流程图及核心代码和执行结果展示:
(其中用到的hostStr,oidStr,portStr,comStr分别代表主机、对象标识符、端口、共同体的字符串形式)
1) Get及GetNext操作:
A. 执行流程图:
图3-2 Get及GetNext执行流程
B. 核心代码:
SnmpTarget target = new SnmpTarget();
//新建SnmpTarget对象(原类参见AdventNet SNMP API)
target.setTargetHost(hostStr);
target.setTargetPort(Integer.valueOf(portStr).intValue());
target.setObjectID(oidStr);
target.setCommunity(comStr);
//设置target的各项参数
if(source==get||source==getB)
result=target.snmpGet();
//执行SNMP协议中的Get操作
else
{
result=target.snmpGetNext();
//执行SNMP协议中的GetNext操作
oid.setText(target.getObjectID());
}
if(result==null)
{
mess.append(target.getErrorString()+"\n");
//显示错误或操作失败的信息
}
else
{
mess.append("HOST:"+target.getTargetHost()+"\tOID:"+target.getSnmpOID()+"\n");
mess.append("Response received. Value:\n" + result+"\n");
//展示操作得到的结果
result=null;
}
C. 结果展示:
图3-3 Get及GetNext操作的结果展示
(注:中间蓝色字体部分为取得的结果,如:OID:.1.3.6.1.2.1.1.1.0代表system组的sysDescr,即对系统的软硬件描述信息,这些都可以在前面给出的相应的表中查到)
2) GetTable操作:
A. 执行流程图:
图3-4 GetTable操作执行流程图
B. 核心代码:
SnmpTablePanel snmptablepanel=new SnmpTablePanel();
//新建SnmpTablePanel对象,用于呈现取表的结果(原类请参见Advent SNMP API)
snmptablepanel.setTargetHost(hostStr);
snmptablepanel.setTargetPort(Integer.valueOf(portStr).intValue());
snmptablepanel.setCommunity(comStr);
//设置snmptablepanel取表所需要的各项参数
try
{
snmptablepanel.loadMibs("RFC1213-MIB");
//装载MIB模型
snmptablepanel.setTableOID(oidStr);
//设置对象ID,必须在loadMib之后
tableFrame(snmptablepanel,oidStr).setVisible(true);
//调用tableFrame(),将返回的JFrame显示
}
catch (Exception ex)
{
JOptionPane.showMessageDialog(this,ex,"Error!",JOptionPane.ERROR_MESSAGE);
//提示出错信息,如错误的OID
}
其中tableFrame(snmptablepanel,oidStr)方法的定义如下:
JFrame tableFrame(JPanel panel,String title)
{
//此方法将传递的SnmpTablePanel显示在新建的JFrame里,并返回
JFrame frame=new JFrame(title);
int x,y;
Dimension size=Toolkit.getDefaultToolkit().getScreenSize();
x=(size.width-700)/2;
y=(size.height-400)/2;
frame.setSize(700,400);
frame.setLocation(x,y);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(panel);
return(frame);
}
C. 结果展示:
图3-5 用GetTable操作得到的tcpConnTable表
(注:tcpConnTable表给出的是运行Snmp代理进程的网络设备当前存在的所有TCP连接的情况,图中从左至右的字段分别代表TCP连接状态,本地地址和端口号,远程地址和端口号。利用GetTable操作同样可以得到其它的表的相关信息,如ifTable,udpTable等)
3) Set操作:
A. 执行流程图:
图3-6 Set操作执行流程图
B. 核心代码:
//Set操作跟前面的Get及GetNext的初始化部分基本相同
String writeCommStr=String.valueOf(writeComm.getPassword());
//Write Community用于设置操作的身份验证
String valueStr=setValue.getText();
if(writeCommStr.equals("")||valueStr.equals(""))
{
JOptionPane.showMessageDialog(this,"No WriteCommunity Or Set Value !","Error!",JOptionPane.WARNING_MESSAGE);
}
else
{
SnmpTarget target = new SnmpTarget();
target.setTargetHost(hostStr);
target.setTargetPort(Integer.valueOf(portStr).intValue());
target.setObjectID(oidStr);
target.setCommunity(comStr);
target.setWriteCommunity(writeCommStr);
try
{
result=target.snmpSet(valueStr);
//即执行SNMP协议中的Set操作
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(this,ex,"Error!",JOptionPane.WARNING_MESSAGE);
//弹出抛出的异常信息
}
if(result==null)
{
mess.append(target.getErrorString()+"\n");
//显示出错信息于结果区
}
else
{
//展示设置成功的相关信息于结果区
mess.append("HOST:"+target.getTargetHost()+"\tOID:"+target.getSnmpOID()+"\n");
mess.append("Set Success!. \n" + result+"\n");
result=null;
}
}
四,总结
SNMP是一种简单的、SNMP管理进程和SNMP代理进程之间的请求-应答协议,也上一种易于实现的基本的网络管理工具,它能够满足短期的管理要求。本文详细介绍了SNMP 及相关协议、模型的原理。描述了协议工作及信息采集的过程,并用程序实现了初步查看网络设备的状态。
在设计的过程中,我们收获不少,学到了许多网络管理方面的知识,并且把理论与实践相结合,真正实现了代码级别的网络设备信息采集。在设计完成后,我们不仅对Java语言有了更深的认识,还初步掌握了利用开发工具包进行程序开发的过程和要点。此次设计让我们积累了用Java进程网络编程的宝贵经验,而设计的成果也让我们对Java语言以及网络产生了更深厚的兴趣。
我们还发现,只要足够努力,平时看起来非常复杂,让人望而生畏的工作其实并不难,战胜困难的过程其实就是知识与经验积累的过程。
参考文献
[1]. 杨家海 任宪坤 王沛瑜