使用snmp4j实现get、set、trap

来源:互联网 发布:制作单片机最小系统 编辑:程序博客网 时间:2024/06/07 17:24

上一篇文章讲了Snmp的一些基本概念,接下来,我们使用Java的开源组件snmp4j来实现一下Snmp里的各种功能。首先是上一篇文章中的那个例子。即通过snmp获取机器名。

snmp4j的jar包可以在它的官方网站http://www.snmp4j.org/上下载,我就不啰嗦了。

view plaincopy to clipboardprint?
  1. import java.io.IOException;  
  2.   
  3. import java.util.Vector;  
  4.   
  5.   
  6. import org.snmp4j.CommunityTarget;  
  7.   
  8. import org.snmp4j.PDU;  
  9.   
  10. import org.snmp4j.Snmp;  
  11.   
  12. import org.snmp4j.TransportMapping;  
  13.   
  14. import org.snmp4j.event.ResponseEvent;  
  15.   
  16. import org.snmp4j.mp.SnmpConstants;  
  17.   
  18. import org.snmp4j.smi.Address;  
  19.   
  20. import org.snmp4j.smi.GenericAddress;  
  21.   
  22. import org.snmp4j.smi.OID;  
  23.   
  24. import org.snmp4j.smi.OctetString;  
  25.   
  26. import org.snmp4j.smi.VariableBinding;  
  27.   
  28. import org.snmp4j.transport.DefaultUdpTransportMapping;  
  29.   
  30.   
  31. public class SnmpUtil {  
  32.   
  33.   
  34.        private Snmp snmp = null;  
  35.   
  36.   
  37.        private Address targetAddress = null;  
  38.   
  39.   
  40.        public void initComm() throws IOException {  
  41.   
  42.                 
  43.   
  44.               // 设置Agent方的IP和端口  
  45.   
  46.               targetAddress = GenericAddress.parse("udp:127.0.0.1/161");  
  47.   
  48.               TransportMapping transport = new DefaultUdpTransportMapping();  
  49.   
  50.               snmp = new Snmp(transport);  
  51.   
  52.               transport.listen();  
  53.   
  54.        }  
  55.   
  56.   
  57.        public void sendPDU() throws IOException {  
  58.   
  59.               // 设置 target  
  60.   
  61.               CommunityTarget target = new CommunityTarget();  
  62.   
  63.               target.setCommunity(new OctetString("public"));  
  64.   
  65.               target.setAddress(targetAddress);  
  66.   
  67.               // 通信不成功时的重试次数  
  68.   
  69.               target.setRetries(2);  
  70.   
  71.               // 超时时间  
  72.   
  73.               target.setTimeout(1500);  
  74.   
  75.               target.setVersion(SnmpConstants.version1);  
  76.   
  77.               // 创建 PDU  
  78.   
  79.               PDU pdu = new PDU();  
  80.   
  81.               pdu.add(new VariableBinding(new OID(new int[] { 136121150 })));  
  82.   
  83.               // MIB的访问方式  
  84.   
  85.               pdu.setType(PDU.GET);  
  86.   
  87.               // 向Agent发送PDU,并接收Response  
  88.   
  89.               ResponseEvent respEvnt = snmp.send(pdu, target);  
  90.   
  91.               // 解析Response  
  92.   
  93.               if (respEvnt != null && respEvnt.getResponse() != null) {  
  94.   
  95.                      Vector<VariableBinding> recVBs = respEvnt.getResponse()  
  96.   
  97.                                    .getVariableBindings();  
  98.   
  99.                      for (int i = 0; i < recVBs.size(); i++) {  
  100.   
  101.                             VariableBinding recVB = recVBs.elementAt(i);  
  102.   
  103.                             System.out.println(recVB.getOid() + " : " + recVB.getVariable());  
  104.   
  105.                      }  
  106.   
  107.               }  
  108.   
  109.        }  
  110.   
  111.   
  112.        public static void main(String[] args) {  
  113.   
  114.               try {  
  115.   
  116.                      SnmpUtil util = new SnmpUtil();  
  117.   
  118.                      util.initComm();  
  119.   
  120.                      util.sendPDU();  
  121.   
  122.               } catch (IOException e) {  
  123.   
  124.                      e.printStackTrace();  
  125.   
  126.               }  
  127.   
  128.        }  
  129.   
  130. }  

[java] view plain copy
  1. import  
  2.  java.io.IOException;  
  3. import java.util.Vector;  
  4.   
  5. import org.snmp4j.CommunityTarget;  
  6. import org.snmp4j.PDU;  
  7. import org.snmp4j.Snmp;  
  8. import org.snmp4j.TransportMapping;  
  9. import org.snmp4j.event.ResponseEvent;  
  10. import org.snmp4j.mp.SnmpConstants;  
  11. import org.snmp4j.smi.Address;  
  12. import org.snmp4j.smi.GenericAddress;  
  13. import org.snmp4j.smi.OID;  
  14. import org.snmp4j.smi.OctetString;  
  15. import org.snmp4j.smi.VariableBinding;  
  16. import org.snmp4j.transport.DefaultUdpTransportMapping;  
  17.   
  18. public class SnmpUtil {  
  19.   
  20.        private Snmp snmp = null;  
  21.   
  22.        private Address targetAddress = null;  
  23.   
  24.        public void initComm() throws IOException {  
  25.                 
  26.               // 设置Agent方的IP和端口  
  27.               targetAddress = GenericAddress.parse("udp:127.0.0.1/161");  
  28.               TransportMapping transport = new   
  29. DefaultUdpTransportMapping();  
  30.               snmp = new Snmp(transport);  
  31.               transport.listen();  
  32.        }  
  33.   
  34.        public void sendPDU() throws IOException {  
  35.               // 设置 target  
  36.               CommunityTarget target = new CommunityTarget();  
  37.               target.setCommunity(new OctetString("public"));  
  38.               target.setAddress(targetAddress);  
  39.               // 通信不成功时的重试次数  
  40.               target.setRetries(2);  
  41.               // 超时时间  
  42.               target.setTimeout(1500);  
  43.               target.setVersion(SnmpConstants.version1);  
  44.               // 创建 PDU  
  45.               PDU pdu = new PDU();  
  46.               pdu.add(new VariableBinding(new OID(new int[] { 136,   
  47. 121150 })));  
  48.               // MIB的访问方式  
  49.               pdu.setType(PDU.GET);  
  50.               // 向Agent发送PDU,并接收Response  
  51.               ResponseEvent respEvnt = snmp.send(pdu, target);  
  52.               // 解析Response  
  53.               if (respEvnt != null && respEvnt.getResponse() !=   
  54. null) {  
  55.                      Vector<VariableBinding> recVBs =   
  56. respEvnt.getResponse()  
  57.                                    .getVariableBindings();  
  58.                      for (int i = 0; i < recVBs.size(); i++) {  
  59.                             VariableBinding recVB = recVBs.elementAt(i);  
  60.                             System.out.println(recVB.getOid() + " : " +   
  61. recVB.getVariable());  
  62.                      }  
  63.               }  
  64.        }  
  65.   
  66.        public static void main(String[] args) {  
  67.               try {  
  68.                      SnmpUtil util = new SnmpUtil();  
  69.                      util.initComm();  
  70.                      util.sendPDU();  
  71.               } catch (IOException e) {  
  72.                      e.printStackTrace();  
  73.               }  
  74.        }  
  75. }  

上面的这段代码直接参考snmp4j API说明文档中提供的例子,是一个最简单的snmp4j的应用。只要你的机器里安装了snmp通讯组件,上面的代码应该可以运行成功。

在上一个例子中,我们只做了读取的工作,接下来,我们进行一下设置操作,通过Snmp修改读取的机器名。
    public的默认权限是只读,要想进行写操作,我们必须进行手动的设置。具体的做法是:进入管理工具→服务,找到Snmp Service→属性→安全。在这个选项卡中我们可以看到public的权限是只读,你可以修改public的权限,也可以重新创建一个community。从安全角度来讲当然应该新建一个,在这里为了测试方便,我就直接给public添加写入权限了。
    接下来就可以编写代码了,我把上面的例子重构一下,代码如下:

 

view plaincopy to clipboardprint?
  1. import java.io.IOException;  
  2.   
  3. import java.util.Vector;  
  4.   
  5.   
  6. import org.snmp4j.CommunityTarget;  
  7.   
  8. import org.snmp4j.PDU;  
  9.   
  10. import org.snmp4j.Snmp;  
  11.   
  12. import org.snmp4j.TransportMapping;  
  13.   
  14. import org.snmp4j.event.ResponseEvent;  
  15.   
  16. import org.snmp4j.mp.SnmpConstants;  
  17.   
  18. import org.snmp4j.smi.Address;  
  19.   
  20. import org.snmp4j.smi.GenericAddress;  
  21.   
  22. import org.snmp4j.smi.OID;  
  23.   
  24. import org.snmp4j.smi.OctetString;  
  25.   
  26. import org.snmp4j.smi.VariableBinding;  
  27.   
  28. import org.snmp4j.transport.DefaultUdpTransportMapping;  
  29.   
  30.   
  31. public class SnmpUtil {  
  32.   
  33.   
  34.        private Snmp snmp = null;  
  35.   
  36.   
  37.        private Address targetAddress = null;  
  38.   
  39.   
  40.        public void initComm() throws IOException {  
  41.   
  42.                 
  43.   
  44.               // 设置Agent方的IP和端口  
  45.   
  46.               targetAddress = GenericAddress.parse("udp:127.0.0.1/161");  
  47.   
  48.               TransportMapping transport = new DefaultUdpTransportMapping();  
  49.   
  50.               snmp = new Snmp(transport);  
  51.   
  52.               transport.listen();  
  53.   
  54.        }  
  55.   
  56.   
  57.        public ResponseEvent sendPDU(PDU pdu) throws IOException {  
  58.   
  59.               // 设置 target  
  60.   
  61.               CommunityTarget target = new CommunityTarget();  
  62.   
  63.               target.setCommunity(new OctetString("public"));  
  64.   
  65.               target.setAddress(targetAddress);  
  66.   
  67.               // 通信不成功时的重试次数  
  68.   
  69.               target.setRetries(2);  
  70.   
  71.               // 超时时间  
  72.   
  73.               target.setTimeout(1500);  
  74.   
  75.               target.setVersion(SnmpConstants.version1);  
  76.   
  77.               // 向Agent发送PDU,并返回Response  
  78.   
  79.               return snmp.send(pdu, target);  
  80.   
  81.        }  
  82.   
  83.          
  84.   
  85.        public void setPDU() throws IOException {  
  86.   
  87.               // set PDU  
  88.   
  89.               PDU pdu = new PDU();  
  90.   
  91.               pdu.add(new VariableBinding(new OID(new int[] { 136121150 }), new OctetString("SNMPTEST")));  
  92.   
  93.               pdu.setType(PDU.SET);  
  94.   
  95.               sendPDU(pdu);  
  96.   
  97.        }  
  98.   
  99.          
  100.   
  101.        public void getPDU() throws IOException {  
  102.   
  103.               // get PDU  
  104.   
  105.               PDU pdu = new PDU();  
  106.   
  107.               pdu.add(new VariableBinding(new OID(new int[] { 136121150 })));  
  108.   
  109.               pdu.setType(PDU.GET);  
  110.   
  111.               readResponse(sendPDU(pdu));  
  112.   
  113.        }  
  114.   
  115.          
  116.   
  117.        public void readResponse(ResponseEvent respEvnt) {  
  118.   
  119.               // 解析Response  
  120.   
  121.               if (respEvnt != null && respEvnt.getResponse() != null) {  
  122.   
  123.                      Vector<VariableBinding> recVBs = respEvnt.getResponse()  
  124.   
  125.                                    .getVariableBindings();  
  126.   
  127.                      for (int i = 0; i < recVBs.size(); i++) {  
  128.   
  129.                             VariableBinding recVB = recVBs.elementAt(i);  
  130.   
  131.                             System.out.println(recVB.getOid() + " : " + recVB.getVariable());  
  132.   
  133.                      }  
  134.   
  135.               }  
  136.   
  137.        }  
  138.   
  139.          
  140.   
  141.        public static void main(String[] args) {  
  142.   
  143.               try {  
  144.   
  145.                      SnmpUtil util = new SnmpUtil();  
  146.   
  147.                      util.initComm();  
  148.   
  149.                      util.setPDU();  
  150.   
  151.                      util.getPDU();  
  152.   
  153.               } catch (IOException e) {  
  154.   
  155.                      e.printStackTrace();  
  156.   
  157.               }  
  158.   
  159.        }  
  160.   
  161. }  

[java] view plain copy
  1. import  
  2.  java.io.IOException;  
  3. import java.util.Vector;  
  4.   
  5. import org.snmp4j.CommunityTarget;  
  6. import org.snmp4j.PDU;  
  7. import org.snmp4j.Snmp;  
  8. import org.snmp4j.TransportMapping;  
  9. import org.snmp4j.event.ResponseEvent;  
  10. import org.snmp4j.mp.SnmpConstants;  
  11. import org.snmp4j.smi.Address;  
  12. import org.snmp4j.smi.GenericAddress;  
  13. import org.snmp4j.smi.OID;  
  14. import org.snmp4j.smi.OctetString;  
  15. import org.snmp4j.smi.VariableBinding;  
  16. import org.snmp4j.transport.DefaultUdpTransportMapping;  
  17.   
  18. public class SnmpUtil {  
  19.   
  20.        private Snmp snmp = null;  
  21.   
  22.        private Address targetAddress = null;  
  23.   
  24.        public void initComm() throws IOException {  
  25.                 
  26.               // 设置Agent方的IP和端口  
  27.               targetAddress = GenericAddress.parse("udp:127.0.0.1/161");  
  28.               TransportMapping transport = new   
  29. DefaultUdpTransportMapping();  
  30.               snmp = new Snmp(transport);  
  31.               transport.listen();  
  32.        }  
  33.   
  34.        public ResponseEvent sendPDU(PDU pdu) throws IOException {  
  35.               // 设置 target  
  36.               CommunityTarget target = new CommunityTarget();  
  37.               target.setCommunity(new OctetString("public"));  
  38.               target.setAddress(targetAddress);  
  39.               // 通信不成功时的重试次数  
  40.               target.setRetries(2);  
  41.               // 超时时间  
  42.               target.setTimeout(1500);  
  43.               target.setVersion(SnmpConstants.version1);  
  44.               // 向Agent发送PDU,并返回Response  
  45.               return snmp.send(pdu, target);  
  46.        }  
  47.          
  48.        public void setPDU() throws IOException {  
  49.               // set PDU  
  50.               PDU pdu = new PDU();  
  51.               pdu.add(new VariableBinding(new OID(new int[] { 136,   
  52. 121150 }), new OctetString("SNMPTEST")));  
  53.               pdu.setType(PDU.SET);  
  54.               sendPDU(pdu);  
  55.        }  
  56.          
  57.        public void getPDU() throws IOException {  
  58.               // get PDU  
  59.               PDU pdu = new PDU();  
  60.               pdu.add(new VariableBinding(new OID(new int[] { 136,   
  61. 121150 })));  
  62.               pdu.setType(PDU.GET);  
  63.               readResponse(sendPDU(pdu));  
  64.        }  
  65.          
  66.        public void readResponse(ResponseEvent respEvnt) {  
  67.               // 解析Response  
  68.               if (respEvnt != null && respEvnt.getResponse() !=   
  69. null) {  
  70.                      Vector<VariableBinding> recVBs =   
  71. respEvnt.getResponse()  
  72.                                    .getVariableBindings();  
  73.                      for (int i = 0; i < recVBs.size(); i++) {  
  74.                             VariableBinding recVB = recVBs.elementAt(i);  
  75.                             System.out.println(recVB.getOid() + " : " +   
  76. recVB.getVariable());  
  77.                      }  
  78.               }  
  79.        }  
  80.          
  81.        public static void main(String[] args) {  
  82.               try {  
  83.                      SnmpUtil util = new SnmpUtil();  
  84.                      util.initComm();  
  85.                      util.setPDU();  
  86.                      util.getPDU();  
  87.               } catch (IOException e) {  
  88.                      e.printStackTrace();  
  89.               }  
  90.        }  
  91. }  

如果控制台打出“1.3.6.1.2.1.1.5.0 : SNMPTEST”的消息,就说明我们的操作成功啦!

以上代码在WindowsXP下测试成功。


前一篇文章讲了如何用snmp4j实现set和get的功能,今天讲如何接收trap。

snmp4j提供了一个抽象类CommandResponder 类用于接收trap,这个类里面有一个必须实现 的方法processPdu() ,当接收到trap,会自动进入这个方法,因此我们可以将对trap的处理写在这里。

view plain copy to clipboard print ?
  1. private  TransportMapping transport =  null ;  
  2.   
  3.   
  4.        public   void  initComm()  throws  IOException {  
  5.   
  6.   
  7.               // 设置Agent方的IP和端口   
  8.   
  9.               targetAddress = GenericAddress.parse("udp:192.168.1.1/161" );  
  10.   
  11.               // 设置接收trap的IP和端口   
  12.   
  13.               transport = new  DefaultUdpTransportMapping( new  UdpAddress(  
  14.   
  15.                             "192.168.1.2/162" ));  
  16.   
  17.               snmp = new  Snmp(transport);  
  18.   
  19.   
  20.               CommandResponder trapRec = new  CommandResponder() {  
  21.   
  22.                      public   synchronized   void  processPdu(CommandResponderEvent e) {  
  23.   
  24.                             // 接收trap   
  25.   
  26.                             PDU command = e.getPDU();  
  27.   
  28.                             if  (command !=  null ) {  
  29.   
  30.                                    System.out.println(command.toString());  
  31.   
  32.                             }  
  33.   
  34.                      }  
  35.   
  36.               };  
  37.   
  38.               snmp.addCommandResponder(trapRec);  
  39.   
  40.   
  41.               transport.listen();  
  42.   
  43.        }  

[java] view plain copy
  1. private  
  2.  TransportMapping transport = null;  
  3.   
  4.        public void initComm() throws IOException {  
  5.   
  6.               // 设置Agent方的IP和端口  
  7.               targetAddress =   
  8. GenericAddress.parse("udp:192.168.1.1/161");  
  9.               // 设置接收trap的IP和端口  
  10.               transport = new DefaultUdpTransportMapping(new UdpAddress(  
  11.                             "192.168.1.2/162"));  
  12.               snmp = new Snmp(transport);  
  13.   
  14.               CommandResponder trapRec = new CommandResponder() {  
  15.                      public synchronized void   
  16. processPdu(CommandResponderEvent e) {  
  17.                             // 接收trap  
  18.                             PDU command = e.getPDU();  
  19.                             if (command != null) {  
  20.                                      
  21. System.out.println(command.toString());  
  22.                             }  
  23.                      }  
  24.               };  
  25.               snmp.addCommandResponder(trapRec);  
  26.   
  27.               transport.listen();  
  28.        }  

其中targetAddress指Agent端也就是trap发 送, transport 指trap接收方,这里就是本机,假设IP是192.168.1.2,但注意不能写成127.0.0.1。

因为我们无法得知trap什么时候会发送,所以需要有一个线程等待trap的到来,在这个例子中我们使用wait()来等待trap的到来,具体应 用中就要根据实际情况来做了。

view plain copy to clipboard print ?
  1. public   synchronized   void  listen() {  
  2.   
  3.               System.out.println("Waiting for traps.." );  
  4.   
  5.               try  {  
  6.   
  7.                      this .wait(); //Wait for traps to come in   
  8.   
  9.               } catch  (InterruptedException ex) {  
  10.   
  11.                      System.out.println("Interrupted while waiting for traps: "  + ex);  
  12.   
  13.                      System.exit(-1 );  
  14.   
  15.               }  
  16.   
  17.        }  
  18.   
  19.          
  20.   
  21.        public   static   void  main(String[] args) {  
  22.   
  23.               try  {  
  24.   
  25.                      SnmpUtil util = new  SnmpUtil();  
  26.   
  27.                      util.initComm();  
  28.   
  29.                      util.listen();  
  30.   
  31.               } catch  (IOException e) {  
  32.   
  33.                      e.printStackTrace();  
  34.   
  35.               }  
  36.   
  37.        }  

[java] view plain copy
  1. public  
  2.  synchronized void listen() {  
  3.               System.out.println("Waiting for traps..");  
  4.               try {  
  5.                      this.wait();//Wait for traps to come in  
  6.               } catch (InterruptedException ex) {  
  7.                      System.out.println("Interrupted while waiting for   
  8. traps: " + ex);  
  9.                      System.exit(-1);  
  10.               }  
  11.        }  
  12.          
  13.        public static void main(String[] args) {  
  14.               try {  
  15.                      SnmpUtil util = new SnmpUtil();  
  16.                      util.initComm();  
  17.                      util.listen();  
  18.               } catch (IOException e) {  
  19.                      e.printStackTrace();  
  20.               }  
  21.        }  

将上面的代码添加到原来的例子中,就可以接收trap了。

但是还有一个问题,如何让192.168.1.1发送trap呢?这个也可以使用snmp4j来做。其实发送trap和发送set、get PDU是类似的,同样是发送PDU,只不过类型不一样。我们把前面的例子复制到192.168.1.1,在里面添加一段代码:

view plain copy to clipboard print ?
  1. public   void  setTrap()  throws  IOException {  
  2.   
  3.         // 构造Trap PDU   
  4.   
  5.         PDU pdu = new  PDU();  
  6.   
  7.         pdu.add(new  VariableBinding( new  OID( ".1.3.6.1.2.3377.10.1.1.1.1" ),  
  8.   
  9.                       new  OctetString( "SnmpTrap" )));  
  10.   
  11.         pdu.setType(PDU.TRAP);  
  12.   
  13.         sendPDU(pdu);  
  14.   
  15.         System.out.println("Trap sent successfully." );  
  16.   
  17.     }  

[java] view plain copy
  1. public  
  2.  void setTrap() throws IOException {  
  3.         // 构造Trap PDU  
  4.         PDU pdu = new PDU();  
  5.         pdu.add(new VariableBinding(new   
  6. OID(".1.3.6.1.2.3377.10.1.1.1.1"),  
  7.                       new OctetString("SnmpTrap")));  
  8.         pdu.setType(PDU.TRAP);  
  9.         sendPDU(pdu);  
  10.         System.out.println("Trap sent successfully.");  
  11.     }  

这里PDU的OID和Value可以自己构造,无需使用特定的值。

然后修改地址
targetAddress = GenericAddress.parse ( "udp:192.168.1.2/162" );
transport new DefaultUdpTransportMapping();

另外需要修改target的version,即改为target.setVersion(SnmpConstants. version2c ) 为什么要这样改我 也没搞清楚,总之verion1收不到。

接下来修改main()函数,调用setTrap()。

然后回到本机运行刚才的例子,当控制台显示“Waiting for traps..”时,运行Agent端的例子。此时如果192.168.1.2打出我们刚刚设置的PDU的信息,就说明Trap的收发成功了。



0 0
原创粉丝点击