码迷,mamicode.com
首页 > 移动开发 > 详细

Android实现snmp协议(一)

时间:2015-02-08 21:52:46      阅读:490      评论:0      收藏:0      [点我收藏+]

标签:

2015年一月初。接到华为一位老师的电话,让我帮忙做一款他们在北京展会上要用到的App,该App能够展示华为的网络设备运行状态并可以设置一些简单的参数,包括AP、LSW、AP、AR等。

华为老师跟我说他们是使用snmp协议v2c的版本进行管理的,这意味着我也得在Android设备实现该协议,并与他们的网络设备交互。

回去认真研究了一下并请教了一些对这块比较熟悉的小伙伴,总算对snmp有了一些粗浅的认识。

snmp是指简单网络设备管理协议,顾名思义就是对网络设备进行管理的通用标准协议,属于TCP/IP的应用层,snmp的服务器端占用的端口是161,客户端占用的是162(基于UDP协议)。

在windows上开启snmp协议可参照http://blog.csdn.net/zougangx/article/details/6977936。
需要注意的一点是:SNMP Service属性的安全选项卡中设置接受来自任何主机的snmp数据包,以便我们调试。
技术分享

对已经建立了连接的两个设备之间,该协议使用了OID(对象标示符)作为查询的内容,OID的内容具体可参考http://www.cnblogs.com/aspx-net/p/3554044.html。OID有一部分是协议定义好的,有一部分设备厂商可以自己定义。

完成以上的步骤,并熟悉了基本的OID指令后,网上有写朋友说就可以使用Paessler SNMP Tester进行调试了,但是本人在实际操作中没有这么顺利,Paessler SNMP Tester一直显示noresponse,转而使用snmputil。(Paessler SNMP Tester和snmputil都是windows端测试snmp协议的工具,Paessler SNMP Tester具有图形化界面,snmputil没有,关于snmputil的操作可以参考http://blog.chinaunix.net/uid-21857285-id-3340217.html)

在使用snmputil的时候出现error on SnmpMgrRequest 40错误,参考以下网址得到解决:http://blog.csdn.net/wqjsir/article/details/8472006,在这篇文章中对陷阱选项卡进行了配置。至此,我的snmputil和Paessler SNMP Tester才正常的运行起来!

在计算机的服务列表中,可以看到:
技术分享

其中Trap消息是需要手动去开启的,而service是自动开启。至于snmp trap服务怎么使用,snmp service的陷阱选项卡的设置原因我也不是很清楚,也希望有人知道的话不吝赐教,暂时不影响我做项目也没深入研究下去。

当两个服务都开启后,可以使用netstat -an|findstr "162"或netstat -an|findstr "161"查看端口是否开发,161开启之后就已经可以做本地测试了。

技术分享

snmp协议是TCP/IP协议,是用c系语言完成的,本人以前移植过的uip1.0也是用c语言写的。而Android必须使用Java来实现,为此,本人首先使用了snmp4j这个jar包,建立了Java工程,仿造官方文档的示例,coding如下(需引入snmp4j的两个jar包):
class SnmpManager {

     private TransportMapping transportMapping = null;
     private Snmp snmp = null;
     private int version;

     public final static int version1 = SnmpConstants. version1;
     public final static int version2c = SnmpConstants.version2c;
     public final static int version3 = SnmpConstants. version3;

     /**
      * 构造方法
      * @param version
      */
     public SnmpManager( int version) {
            this. version = version;
            try {
                 // 设置成Udp协议
                 transportMapping = new DefaultUdpTransportMapping();
                 snmp = new Snmp( transportMapping);

                 if (version == version3) {
                      // 设置安全信息
                     USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
                     SecurityModels. getInstance().addSecurityModel(usm);
                }
                 transportMapping.listen();
           } catch (Exception e) {
                e.printStackTrace();
                System. out.println(e);
           }
     }

     /**
      * @param sync
      * @param bro
      * @param pdu
      * @param addr
      * 发送消息方法
      */
     public void sendMsg(boolean sync, final boolean bro, PDU pdu, String addr) {
           Address targetAddres = GenericAddress. parse(addr);
           Target target = null;
            if ( this. version == version3) {
                 snmp.getUSM().addUser( new OctetString( "MD5DES"), new UsmUser( new OctetString( "MD5DES"), AuthMD5. ID, new OctetString("MD5DESUserAuthPassword" ), PrivDES.ID, new OctetString("MD5DESUserPrivPassword" )));
                target = new UserTarget();
                 // 设置安全级别
                target.setSecurityLevel(SecurityLevel. AUTH_PRIV);
                target.setSecurityName( new OctetString("MD5DES"));
                target.setVersion(SnmpConstants. version3);
           } else {
                target = new CommunityTarget();
                 if ( this. version == version1) {
                     target.setVersion( version1);
                     ((CommunityTarget) target).setCommunity(new OctetString("public" ));
                } else {
                     target.setVersion( version2c);
                     ((CommunityTarget) target).setCommunity(new OctetString("public" ));
                }
           }

           target.setAddress(targetAddres);
           target.setRetries(2);
           target.setTimeout(1000);

            if (sync) {
                 // 发送报文 并且接受响应
                ResponseEvent response = null;
                 try {
                     response = snmp.send(pdu, target);
                } catch (IOException e) {
                      // TODO Auto-generated catch block
                     e.printStackTrace();
                     System. out.println(e);
                }
                 // 处理响应
                System. out.println( "Synchronize message from " + response.getPeerAddress() + "/nrequest:" + response.getRequest() + "/nresponse:" + response.getResponse());
                
           } else {
                ResponseListener listener = new ResponseListener() {
                      @Override
                      public void onResponse(ResponseEvent event) {
                            if (!bro) {
                                ((Snmp) event.getSource()).cancel(event.getRequest(), this );
                           }
                            // 处理响应
                           PDU request = event.getRequest();
                           PDU response = event.getResponse();
                           System. out.println( "Asynchronise message from " + event.getPeerAddress() + "/nrequest:" + request + "/nresponse:" + response);
                     }
                };
                 try {
                      snmp.send(pdu, target, null, listener);
                } catch (IOException e) {
                     e.printStackTrace();
                     System. out.println(e);
                }
           }
     }
}

public class SnmpTest {

     public static String myVersion = "";
     static boolean sync = false;
     static boolean bro = false;

     /**
      * 主函数
      * @param args
      */
     public static void main(String[] args) {

           SnmpManager manager = new SnmpManager(SnmpConstants.version2c );
            // 构造报文
           PDU pdu = new PDU();
            // PDU pdu = new ScopedPDU(); version3使用
            // 设置要获取的对象ID
           OID oids = new OID( "1.3.6.1.2.1.1.1.0");
//         OID oids = new OID(new int [] { 1, 3, 6, 1, 2, 1, 1, 1, 0 });
           pdu.add( new VariableBinding(oids));
            // 设置报文类型
           pdu.setType(PDU. GET);
//         ((ScopedPDU) pdu).setContextName(new OctetString("priv")); 
            // 发送消息 其中最后一个是想要发送的目标地址
           manager.sendMsg( true, true, pdu, "udp:127.0.0.1/161");
           
     }
}

运行结果如下:
技术分享

等我把这段Java代码移植到Android工程中时,却不起作用了。我百度、google、stackoverflow等一些网站都看过了,在stackoverflow上有位朋友也是遇到和我一样的问题,有人回复snmp4j无法在Android上无法使用,究竟为什么,本人也不能解释给大家听,需要更厉害的人了!

因为是华为老师的项目,我不能这样尥蹶子,就继续查找相关资料,我想应该有人做出了类似snmp4j的Android版本吧,功夫不负有心人。
这个网站的闭源包提供了这个功能,做snmp的开发者,不妨研读一下,我就是在使用了此网站的开发包,完成了snmp的协议。
技术分享

Android实现snmp协议(一)

标签:

原文地址:http://blog.csdn.net/leirenbaobao/article/details/43647025

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!