Android實現snmp協議(一)

來源:互聯網
上載者:User

標籤:

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版本吧,功夫不負有心人。https://www.webnms.com/snmpapi-android/index.html這個網站的閉源包提供了這個功能,做snmp的開發人員,不妨研讀一下,我就是在使用了此網站的開發包,完成了snmp的協議。

Android實現snmp協議(一)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.