snmpsharpnet是基于C#开发一个开源组件,主要是为了方便使用SNMP协议而生,支持各种SNMP各种版本、各种指令的一个优秀组件。其官方网站是:,里面有很多C#使用例子及相关介绍。
有人也应用它来做了一些小应用,如博客:
这类开发能解决什么问题呢?
简单来讲,可以开发相关设备管理及监控的程序。
为了使用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方面的应用应该很少人涉及到,因此对多数人来说,还是比较神秘的东西,本文抛砖引玉,希望与大家一起讨论学习。