天天看點

利用C#開發基于snmpsharpnet基礎的SNMP開發應用snmp是什麼?SNMP基礎簡介SNMP協定學習

由于項目的需要,需要使用SNMP來進行相關的開發,需要在我的程式中利用SNMP的Trap協定給指定的系統程式發送相關的裝置資料資訊, 使得其系統能夠監控到裝置的最新資訊以及狀态,對方隻是提供了一個Java的例子,而我的程式是C#開發的,是以對這方面的知識進行了解學習,完成了相關的功能,本文有感于此,對SNMP方面做了一些開發總結,以求樹碑到此一遊,獨樂不如衆樂,邀興趣之士獵奇探秘.

首先介紹标題的幾個問題,SNMP是什麼,snmpsharpnet又是什麼,開發能解決什麼問題?

SNMP是什麼呢?

簡單來說,SNMP主要就是一種特定的網絡管理協定,用來擷取裝置相關資訊的一種一些,複雜來講,就很講究了,我不在長篇大量介紹重複的内容,需要了解可以參考下面幾篇博文:

 snmpsharpnet又是什麼呢?

這類開發能解決什麼問題呢?

 簡單來講,可以開發相關裝置管理及監控的程式。

為了使用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];

            OctetString community = new OctetString(comname);

            // Define agent parameters class

            // 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);

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

            //區分兩台伺服器的硬碟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();

            result = (SnmpV1Packet)target.Request(pdu, param);

            // If result is null then agent didn't reply or we couldn't parse the reply.

                // ErrorStatus other then 0 is an error returned by  

                    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"));

            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方面的應用應該很少人涉及到,是以對多數人來說,還是比較神秘的東西,本文抛磚引玉,希望與大家一起讨論學習。