SNMP网络管理协议在通信设备中使用得很广,大部分的通信设备的网管接口都支持SNMP标准协议。最近在实际工作做有所接触,下面就说说自己开发过程中的问题和心得。
    一般来讲SNMP由网管终端(如PC上的NMC)和设备中的Agent组成,也就是通常所讲的上位机与下位机。我的工作住要是PC部分的网管的开发。目前我所知道的开源的SNMP开发包有SNMP++和NET-SNMP两个,SNMP++是由HP公司人员开发的,后来公开了源代码,我就是用的SNMP++。NET-SNMP最初是由美国卡内基梅龙大学开发的,后来也成为了一个开源项目。
    要开发SNMP方面的程序就必须要对SNMP协议有基本的认识,SNMP主要由MIB,SMI等部分,MIB就是对每一个被管理对的标识,而SMI则定义了管理的数据编码实现,这些内容都可以在ISO的RFC文档中找到,这就不多说了,看书来得更快。SNMP利用UDP协议来传输数据包,主要有GetRequest报文、GetNextRequest报文、GetResponse报文、SetRequest报文和TRAP报文五种。
    SNMP++是用C++编写,整个库的框架很全,支持SNMPV1、SNMPV2、SNMPV3等版本,全部采用面向对象化设计类结构,使用起来很方便。SNMP++可以网上很多地方下载到,下载后要先编译,有动态DLL和静态LIB两种。编译的时候要注意路径的设置,否则编译是通不过的,多设置一下。下面就是一个GetRequest的简单例子

GenAddress address("192.168.10.169"); //Agent的IP地址 

 if ( !address.valid()) {     

  MessageBox("Invalid Address or DNS Name ");//IP地址有效性检查 

  return; 

 } 

     Oid oid("1.3.6.1.4.1.10811.1.5.1.1.10.1.4");//MIB对象   

 if ( !oid.valid()) {    

  MessageBox("Invalid Oid, " ); 

  return; 

 } 

 snmp_version version=version1;//SNMP版本号,这里是V1    

 int retries=1;//UDP包重发次数,默认值为1         

 int timeout=400; //超时时间 

 OctetStr community("public");//读访问串 

 OctetStr wrCommunity("public");//写访问串 

 int status; 

 Snmp snmp( status);         

 if ( status != SNMP_CLASS_SUCCESS) {//创建SNMP会话 

  MessageBox("SNMP++ Session Create Fail, " ); 

  return ; 

 } 

 Pdu pdu;//够造一个PDU报文                     

 Vb vb;                      

 vb.set_oid( oid);                  

 pdu += vb;                          

 CTarget target( address);//设置网管目标            

 target.set_version( version);          

 target.set_retry( retries);           

 target.set_timeout( timeout);         

 target.set_readcommunity( community);   

 target.set_writecommunity( wrCommunity); 

   if (( status = snmp.get( pdu,target))== SNMP_CLASS_SUCCESS) {//GetRequest操作 

  pdu.get_vb( vb,0); 

  MessageBox( vb.get_printable_oid());//返回的MIB对象 

  MessageBox(vb.get_printable_value());//返回的MIB对象的值(以字符串形式出现) 

 } 

 else { 

  MessageBox( "SNMP++ Get Error"); 

  if ( status == SNMP_CLASS_ERR_STATUS_SET)//出错 

   status = pdu.get_error_status();//打印出错原因 

  MessageBox(snmp.error_msg( status)); 

 }


   SNMP++对各种操作都提供了阻塞和非阻塞操作,阻塞操作要等AGENT返回值或则超时后才返回,而非阻塞则可以立即返回。在实际中要根据情况选择采用哪一种, 非阻塞操作中要加snmp.eventListHolder->SNMPProcessPendingEvents()函数来获取事件。
    有了基本的操作后,网管的主要工作就是对AGENT数据定时的采集,然后分析数据,产生设备告警。一直以来对管理很多设备时,数据采集速度就很慢,找不到很好的解决办法,有待讨论。