Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android實現snmp協議(一)

Android實現snmp協議(一)

編輯:關於Android編程

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一直顯示nZ喎?/kf/ware/vc/" target="_blank" class="keylink">vcmVzcG9uc2WjrNeqtvjKudPDc25tcHV0aWyho6OoUGFlc3NsZXIgU05NUCBUZXN0ZXK6zXNubXB1dGlstrzKx3dpbmRvd3O2y7LiytRzbm1w0K3S6bXEuaS+36OsUGFlc3NsZXIKIFNOTVAgVGVzdGVyvt/T0M280M67r73nw+ajrHNubXB1dGlsw7vT0KOsudjT2nNubXB1dGlstcSy2df3v8nS1LLOv7xodHRwOi8vYmxvZy5jaGluYXVuaXgubmV0L3VpZC0yMTg1NzI4NS1pZC0zMzQwMjE3Lmh0bWwpCjxicj4KCtTayrnTw3NubXB1dGlstcTKsbrys/bP1mVycm9yIG9uCiBTbm1wTWdyUmVxdWVzdCA0MLTtzvOjrLLOv7zS1M/CzfjWt7XDtb294r72o7podHRwOi8vYmxvZy5jc2RuLm5ldC93cWpzaXIvYXJ0aWNsZS9kZXRhaWxzLzg0NzIwMDajrNTa1eLGqs7E1cLW0LbUz93a5dGhz+6/qL340NDBy8Xk1sOho9bBtMujrM7StcRzbm1wdXRpbLrNUGFlc3NsZXIgU05NUCBUZXN0ZXKyxdX9s6O1xNTL0NDG8MC0o6EKCjxicj4KCgrU2rzGy+O7+rXEt/7O8cHQse3W0KOsv8nS1L+0tb2jugoKPGltZyBzcmM9"/uploadfile/Collfiles/20150209/2015020908510559.png" alt="\">

其中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的協議。 \

private void buttonFun() {
		noNull();
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				api = new SnmpAPI();
				session = new SnmpSession(api);

				SnmpPDU pdu = new SnmpPDU();

				UDPProtocolOptions protocol = new UDPProtocolOptions();
				protocol.setRemoteHost(getText(target));
				protocol.setRemotePort(Integer.parseInt(getText(port)));
				pdu.setProtocolOptions(protocol);

				// Build Get request PDU
				pdu.setCommand(SnmpAPI.GET_REQ_MSG);
			    pdu.setCommunity(getText(community));
			    
			    if(version.getSelectedItemPosition()==0){
			    	pdu.setVersion(SnmpAPI.SNMP_VERSION_1);	
			    	
			    }else if(version.getSelectedItemPosition()==1){
			    	pdu.setVersion(SnmpAPI.SNMP_VERSION_2C);
			    	
			    }else if(version.getSelectedItemPosition()==2){
			    	//還需設置MD5 SHA認證密碼等
			    	pdu.setVersion(SnmpAPI.SNMP_VERSION_3);
			    }
			    

				pdu.setTimeout(Integer.parseInt(getText(timeout)));
				pdu.setRetries(Integer.parseInt(getText(retries)));

				// SnmpOID oid = new SnmpOID("1.3.6.1.2.1.1.1.0");
				// SnmpOID oid = new SnmpOID((SnmpOID)(getText(oid)));
				// pdu.addNull(oid);
				
				String oidstr = getText(oid);
				String str[] = oidstr.split("\\.");
				int a[] = new int[9];
				for(int i=0; i
做到這份上,跟華為的老師聯系上了,他們跟我說年前比較忙,拖到年後才能詳談需求業務,我也暫時擱置此項目,去做別的事了。也許有新的情況,我會寫個第二篇,希望對大家有幫助。



  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved