利用C#开发基于snmpsharpnet基础的SNMP开发应用

由于项目的需要,需要使用SNMP来进行相关的开发,需要在我的程序中利用SNMP的Trap协议给指定的系统程序发送相关的设备数据信息, 使得其系统能够监控到设备的最新信息以及状态,对方只是提供了一个Java的例子,而我的程序是C#开发的,因此对这方面的知识进行了解学习,完成了相关的功能,本文有感于此,对SNMP方面做了一些开发总结,以求树碑到此一游,独乐不如众乐,邀兴趣之士猎奇探秘.

 

首先介绍标题的几个问题,SNMP是什么,snmpsharpnet又是什么,开发能解决什么问题?

SNMP是什么呢?

简单来说,SNMP主要就是一种特定的网络管理协议,用来获取设备相关信息的一种一些,复杂来讲,就很讲究了,我不在长篇大量介绍重复的内容,需要了解可以参考下面几篇博文:

SNMP介紹及命令

SNMP基础简介

 

snmpsharpnet又是什么呢?

snmpsharpnet是基于C#开发一个开源组件,主要是为了方便使用SNMP协议而生,支持各种SNMP各种版本、各种指令的一个优秀组件。其官方网站是: http://www.snmpsharpnet.com/,里面有很多C#使用例子及相关介绍。

有人也应用它来做了一些小应用,如博客:c#开发snmp应用
 

这类开发能解决什么问题呢?

 简单来讲,可以开发相关设备管理及监控的程序。

 

为了使用SNMP来进行调试及开发,需要在操作系统中安装SNMP服务(默认系统没有安装),安装和普通的安装Window组件一样的步骤,选定简单网络管理协议组件即可,安装后,在服务中启动SNMP服务即可,如下所示:

 

虽然启动了服务,不过要顺利访问,还需要对系统的社区名称及可以访问的IP地址做配置,否则一样无法取得计算机的相关设备信息,配置对话框是双击服务,打开属性对话框进行配置即可。

           

 利用SNMPSharpNet组件来开发SNMP服务应用,省却了很多复杂的组装操作,非常方便,如获取指定机器的基本信息,可以通过

         private void button1_Click(object sender, EventArgs e)

复制代码
        {
            
//  SNMP community name
            OctetString community  =   new  OctetString( " public " );

            AgentParameters param 
=   new  AgentParameters(community);
            param.Version 
=  SnmpVersion.Ver1;
            IpAddress agent 
=   new  IpAddress( " 192.168.0.50 " );

            
//  Construct target
            UdpTarget target  =   new  UdpTarget((IPAddress)agent,  161 2000 1 );

            
//  Pdu class used for all requests
            Pdu pdu  =   new  Pdu(PduType.Get);
            pdu.VbList.Add(
" 1.3.6.1.2.1.1.1.0 " );  // sysDescr
            pdu.VbList.Add( " 1.3.6.1.2.1.1.2.0 " );  // sysObjectID
            pdu.VbList.Add( " 1.3.6.1.2.1.1.3.0 " );  // sysUpTime
            pdu.VbList.Add( " 1.3.6.1.2.1.1.4.0 " );  // sysContact
            pdu.VbList.Add( " 1.3.6.1.2.1.1.5.0 " );  // sysName

            
//  Make SNMP request
            SnmpV1Packet result  =  (SnmpV1Packet)target.Request(pdu, param);

            
if  (result  !=   null )
            {
                
//  ErrorStatus other then 0 is an error returned by 
                
//  the Agent - see SnmpConstants for error definitions
                 if  (result.Pdu.ErrorStatus  !=   0 )
                {
                    
//  agent reported an error with the request
                     this .txtContent.Text  +=   string .Format( " Error in SNMP reply. Error {0} index {1} \r\n " ,
                        result.Pdu.ErrorStatus,
                        result.Pdu.ErrorIndex);
                }
                
else
                {
                    
//  Reply variables are returned in the same order as they were added
                    
//   to the VbList
                     this .txtContent.Text  +=   string .Format( " sysDescr({0}) ({1}): {2} \r\n " ,
                        result.Pdu.VbList[
0 ].Oid.ToString(), SnmpConstants.GetTypeName(result.Pdu.VbList[ 0 ].Value.Type),
                        result.Pdu.VbList[
0 ].Value.ToString());
                    
this .txtContent.Text  +=   string .Format( " sysObjectID({0}) ({1}): {2} \r\n " ,
                        result.Pdu.VbList[
1 ].Oid.ToString(), SnmpConstants.GetTypeName(result.Pdu.VbList[ 1 ].Value.Type),
                        result.Pdu.VbList[
1 ].Value.ToString());
                    
this .txtContent.Text  +=   string .Format( " sysUpTime({0}) ({1}): {2} \r\n " ,
                        result.Pdu.VbList[
2 ].Oid.ToString(), SnmpConstants.GetTypeName(result.Pdu.VbList[ 2 ].Value.Type),
                        result.Pdu.VbList[
2 ].Value.ToString());
                    
this .txtContent.Text  +=   string .Format( " sysContact({0}) ({1}): {2} \r\n " ,
                        result.Pdu.VbList[
3 ].Oid.ToString(), SnmpConstants.GetTypeName(result.Pdu.VbList[ 3 ].Value.Type),
                        result.Pdu.VbList[
3 ].Value.ToString());
                    
this .txtContent.Text  +=   string .Format( " sysName({0}) ({1}): {2} \r\n " ,
                        result.Pdu.VbList[
4 ].Oid.ToString(), SnmpConstants.GetTypeName(result.Pdu.VbList[ 4 ].Value.Type),
                        result.Pdu.VbList[
4 ].Value.ToString());
                }
            }
            
else
            {
                
this .txtContent.Text  +=   string .Format( " No response received from SNMP agent. \r\n " );
            }
            target.Dispose();
        }
复制代码

 

运行后可以显示指定机器的基本信息,如下所示:

sysDescr(1.3.6.1.2.1.1.1.0) (OctetString): Hardware: x86 Family 6 Model 26 Stepping 5 AT/AT COMPATIBLE - Software: Windows Version 5.2 (Build 3790 Multiprocessor Free) 
sysObjectID(1.3.6.1.2.1.1.2.0) (ObjectId): 1.3.6.1.4.1.311.1.1.3.1.2 
sysUpTime(1.3.6.1.2.1.1.3.0) (TimeTicks): 46d 4h 14m 2s 320ms 
sysContact(1.3.6.1.2.1.1.4.0) (OctetString):  
sysName(1.3.6.1.2.1.1.5.0) (OctetString): TCC-TX 

 

又例如我们可以通过SNMP命令来监控磁盘的空间大小,例子代码如下所示:

复制代码
代码
         private   void  button7_Click( object  sender, EventArgs e)
        {
            
double [] diskstorage1, diskstorage2;

            diskstorage1 
=  snmpget( " 127.0.0.1 " " public " 1 );
            
this .txtContent.Text  +=  Environment.NewLine;
            diskstorage2 
=  snmpget( " 192.168.101.81 " " gci_RW " 2 );
            
// foreach (double dou in diskstorage1)
            
// {
            
//     this.txtContent.Text += string.Format("{0}  GB \r\n", dou.ToString("f2"));
            
// }
        }

        
double [] snmpget( string  ipaddress,  string  comname,  int  i)
        {

            
double  cvolumn  =   0 , dvolumn  =   0 , cvolunmn1  =   0 , dvolumn1  =   0 , cvolumn2  =   0 , dvolumn2  =   0 ;
            
double [] backup  =   new   double [ 6 ];
            
//  SNMP community name
            OctetString community  =   new  OctetString(comname);

            
//  Define agent parameters class
            AgentParameters param  =   new  AgentParameters(community);
            
//  Set SNMP version to 1 (or 2)
            param.Version  =  ( int )SnmpVersion.Ver1;
            
//  Construct the agent address object
            
//  IpAddress class is easy to use here because
            
//   it will try to resolve constructor parameter if it doesn't
            
//   parse to an IP address
            IpAddress agent  =   new  IpAddress(ipaddress);

            
//  Construct target
            UdpTarget target  =   new  UdpTarget((IPAddress)agent,  161 2000 2 );

            
//  Pdu class used for all requests
            Pdu pdu  =   new  Pdu(PduType.Get);
            
// 区分两台服务器的硬盘mib代码
             if  (i  ==   2 )
            {
                pdu.VbList.Add(
" 1.3.6.1.2.1.25.2.3.1.5.2 " );  // 硬盘C盘簇数
                pdu.VbList.Add( " 1.3.6.1.2.1.25.2.3.1.5.3 " );  // 硬盘D盘簇数
                pdu.VbList.Add( " 1.3.6.1.2.1.25.2.3.1.6.2 " ); // 硬盘C盘已用簇数
                pdu.VbList.Add( " 1.3.6.1.2.1.25.2.3.1.6.3 " ); // 硬盘D盘已用簇数
                pdu.VbList.Add( " 1.3.6.1.2.1.25.2.3.1.4.2 " ); // 硬盘C盘分配单元
                pdu.VbList.Add( " 1.3.6.1.2.1.25.2.3.1.4.3 " ); // 硬盘D盘分配单元
            }
            
else   if  (i  ==   1 )
            {
                pdu.VbList.Add(
" 1.3.6.1.2.1.25.2.3.1.5.1 " );  // 硬盘C盘簇数
                pdu.VbList.Add( " 1.3.6.1.2.1.25.2.3.1.5.2 " );  // 硬盘D盘簇数
                pdu.VbList.Add( " 1.3.6.1.2.1.25.2.3.1.6.1 " ); // 硬盘C盘已用簇数
                pdu.VbList.Add( " 1.3.6.1.2.1.25.2.3.1.6.2 " ); // 硬盘D盘已用簇数
                pdu.VbList.Add( " 1.3.6.1.2.1.25.2.3.1.4.1 " ); // 硬盘C盘分配单元
                pdu.VbList.Add( " 1.3.6.1.2.1.25.2.3.1.4.2 " ); // 硬盘D盘分配单元
            }

            SnmpV1Packet result 
=   new  SnmpV1Packet();

            
//  Make SNMP request
            result  =  (SnmpV1Packet)target.Request(pdu, param);

            
//  If result is null then agent didn't reply or we couldn't parse the reply.
             if  (result  !=   null )
            {
                
//  ErrorStatus other then 0 is an error returned by  
                
//  the Agent - see SnmpConstants for error definitions
                 if  (result.Pdu.ErrorStatus  !=   0 )
                {
                    
//  agent reported an error with the request
                     this .txtContent.Text  +=   string .Format( " Error in SNMP reply. Error {0} index {1} \r\n " ,
                        result.Pdu.ErrorStatus,
                        result.Pdu.ErrorIndex);
                }
                
else
                {
                    
//  Reply variables are returned in the same order as they were added
                    
//   to the VbList

                    
int  a  =   int .Parse(result.Pdu.VbList[ 0 ].Value.ToString());
                    
int  b  =   int .Parse(result.Pdu.VbList[ 1 ].Value.ToString());
                    
int  c  =   int .Parse(result.Pdu.VbList[ 2 ].Value.ToString());
                    
int  d  =   int .Parse(result.Pdu.VbList[ 3 ].Value.ToString());
                    
int  num1  =   int .Parse(result.Pdu.VbList[ 4 ].Value.ToString());
                    
int  num2  =   int .Parse(result.Pdu.VbList[ 5 ].Value.ToString());
                    cvolumn 
=  ( double )a  *  num1  /   1024   /   1024   /   1024 ;
                    dvolumn 
=  ( double )b  *  num2  /   1024   /   1024   /   1024 ;
                    cvolunmn1 
=  ( double )c  *  num1  /   1024   /   1024   /   1024 ;
                    dvolumn1 
=  ( double )d  *  num2  /   1024   /   1024   /   1024 ;
                    cvolumn2 
=  cvolumn  -  cvolunmn1;
                    dvolumn2 
=  dvolumn  -  dvolumn1;
                    backup[
0 =  cvolumn;
                    backup[
1 =  dvolumn;
                    backup[
2 =  cvolunmn1;
                    backup[
3 =  dvolumn1;
                    backup[
4 =  cvolumn2;
                    backup[
5 =  dvolumn2;
                    
this .txtContent.Text  +=   string .Format( " c盘空间{0} GB \r\n " , cvolumn.ToString( " f2 " ));
                    
this .txtContent.Text  +=   string .Format( " d盘空间{0} GB \r\n " , dvolumn.ToString( " f2 " ));
                    
this .txtContent.Text  +=   string .Format( " c盘已用空间{0} GB \r\n " , cvolunmn1.ToString( " f2 " ));
                    
this .txtContent.Text  +=   string .Format( " d盘已用空间{0} GB \r\n " , dvolumn1.ToString( " f2 " ));
                    
this .txtContent.Text  +=   string .Format( " c盘剩余空间{0} GB \r\n " , cvolumn2.ToString( " f2 " ));
                    
this .txtContent.Text  +=   string .Format( " d盘剩余空间{0} GB \r\n " , dvolumn2.ToString( " f2 " ));
                }
            }
            
else
            {
                
this .txtContent.Text  +=   string .Format( " No response received from SNMP agent. \r\n " );
            }
            target.Close();

            
return  backup;
        }
复制代码

 

 

出来的结果就是显示各计算机的磁盘信息,如下所示:

复制代码
c盘空间97. 66  GB 
d盘空间73.
25  GB 
c盘已用空间36.
61  GB 
d盘已用空间31.
00  GB 
c盘剩余空间61.
05  GB 
d盘剩余空间42.
25  GB 

c盘空间48.
83  GB 
d盘空间57.
19  GB 
c盘已用空间1.
70  GB 
d盘已用空间6.
68  GB 
c盘剩余空间47.
13  GB 
d盘剩余空间50.
51  GB 
复制代码

 

 

另外利用SNMP可以发送约定的Trap协议到指定的计算机上,从而实现两个计算机上的交互操作,Trap协议可以发送多种数据类型,如字符类型、整形、日期类型、OID类型等信息,发送Trap协议比较简单,如下所示:

         int i = 0;

复制代码
         private   void  button8_Click( object  sender, EventArgs e)
        {
            TrapAgent agent 
=   new  TrapAgent();
            VbCollection col 
=   new  VbCollection();

            
// 连接状态 设备连接状态(0:通信正常 1:通信故障)
            
// 工作温度
            
// 告警描述
             string  desc  =   string .Format( " 测试Trap内容 " );
            col.Add(
new  Oid( " .1.3.6.1.4.1.22014.99.2.1.6.2.1.1.1 " ),  new  Integer32( 0 ));
            col.Add(
new  Oid( " .1.3.6.1.4.1.22014.99.2.1.6.2.1.1.2 " ),  new  Integer32( 30 ));
            col.Add(
new  Oid( " .1.3.6.1.4.1.22014.99.2.1.6.2.4.1.1 " ),  new  OctetString(Encoding.Default.GetBytes(desc)));
            
            
//  Send the trap to the localhost port 162
             string  hostIp  =   " 127.0.0.1 " ;
            
string  community  =   " public " ;
            agent.SendV2Trap(
new  IpAddress(hostIp),  162 , community,
                             
13433 new  Oid( " .1.3.6.1.6.3.1.1.5 " ), col);
            i
++ ;
        }
复制代码

 

 

通过接受数据的控制台,我们能可以查看到Trap协议接受到的情况,如下所示:

 

  由于SNMP方面的应用应该很少人涉及到,因此对多数人来说,还是比较神秘的东西,本文抛砖引玉,希望与大家一起讨论学习。

 

主要研究技术:代码生成工具、Visio二次开发、客户关系管理软件、病人资料管理软件、送水管理软件等共享软件开发
专注于 Winform开发框架Web开发框架、WCF开发框架、微信门户开发框架的研究及应用。
  转载请注明出处:
撰写人:伍华聪   http://www.iqidi.com 
    
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值