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();
}
運行后可以顯示指定機器的基本信息,如下所示:
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命令來監控磁盤的空間大小,例子代碼如下所示:

{
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;
}
出來的結果就是顯示各計算機的磁盤信息,如下所示:
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;
{
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方面的應用應該很少人涉及到,因此對多數人來說,還是比較神秘的東西,本文拋磚引玉,希望與大家一起討論學習。