zoukankan      html  css  js  c++  java
  • 手动解析snmp的dateAndTime类型

    Technorati 标签: snmp,dateAndTime

    原始blog:http://blog.csdn.net/byalc/article/details/486927

     

    由于原作者是基于c++的,我稍作修改,改为JAVA版的.

     

    DateAndTime是Snmpv2中的一种数据类型,它主要提供了对日期时间的描述。我在使用Snmp4j开发包时,发现其不提供对DateAndTime类型的支持,而有时又需要用到该类型,于是,自己写了一个方法解析该类型,可以实现对DateAndTime类型的格式化,并且可以方便地提取各时间项。

    下面是RFC中对DateAndTime的定义:

    DateAndTime ::= OCTET STRING (SIZE (8 | 11))

    -- A date-time specification for the local time of day.

    -- This data type is intended to provide a consistent

    -- method of reporting date information.

    --

    -- field octets contents range

    -- _____ ______ ________ _____

    -- 1 1-2 year 0..65536

    -- (in network byte order)

    -- 2 3 month 1..12

    -- 3 4 day 1..31

    -- 4 5 hour 0..23

    -- 5 6 minutes 0..59

    -- 6 7 seconds 0..60

    -- (use 60 for leap-second)

    -- 7 8 deci-seconds 0..9

    -- 8 9 direction from UTC "+" / "-"

    -- (in ascii notation)

    -- 9 10 hours from UTC 0..11

    -- 10 11 minutes from UTC 0..59

    --

    -- Note that if only local time is known, then

    -- timezone information (fields 8-10) is not present.

    由定义可见,DateAndTime仍然是OCTET STRING类型的数据,只是对每个字节进行了具体的定义。比如前两个字节表示年,第五个字节表示小时等。所以如果某个开发包中没有DateAndTime类型,那么大可以用Octet类型去代替。但是这样做得到的只是一些无意义的乱码而已。因此,实现的关键就在于按照定义对特殊的Octet数据进行正确的解析。

    既然DateAndTime也是Octet String,那么我们就可以按照字节数组来处理他。

     
     
    import java.util.Vector;
     
    import org.apache.log4j.Logger;
    import org.snmp4j.CommandResponderEvent;
    import org.snmp4j.PDU;
    import org.snmp4j.smi.OctetString;
    import org.snmp4j.smi.Variable;
    import org.snmp4j.smi.VariableBinding;
     
    import com.asb.mediation.snmp.SNMPManager;
    import com.asb.mediation.util.INMSLog;
     
     
    public class SNMPAdapter  extends SNMPManager{
        private Logger adapterlog = INMSLog.getInstance().getAdapterLog();
        private Logger recvlog = INMSLog.getInstance().getReceiveLog();
        
        public SNMPAdapter(String snmpIP, String snmpPort){
            super(snmpIP, snmpPort);
        }
        
        @Override
        protected void notifyMsg(CommandResponderEvent event) {
            adapterlog.info("Mapper::notifyMsg>>    =====NOTIFY_ALARM=====");
            
            PDU pdu = event.getPDU();
            Vector vec = pdu.getVariableBindings();
            adapterlog.info("YYWifiMapper::process>>    oid size = " + vec.size());
            
            for (int i = 0; i < vec.size(); i++) {
                String oidNameValue = "";
                VariableBinding vb = (VariableBinding)vec.get(i);
                if (vb.getVariable() instanceof OctetString) {
                    String value = new String(((OctetString)vb.getVariable()).getValue());
                                
                    if(vb.getOid().toString().trim().equals("1.3.6.1.4.1.88888.2") ){
                        oidNameValue = "OID:"+vb.getOid()+"\t"+"value:" + parseDateAndTime(vb.getVariable());    
                    }
                    else{
                        oidNameValue = "OID:"+vb.getOid()+"\t"+"value:" + value.trim();
                    }
                }
                else{                
                    //略
                }
            }
            
        }
        
        public String parseDateAndTime(Variable v){
            adapterlog.info("YYWifiMapper::parseDateAndTime>>    v="+v);
    //        adapterlog.info("YYWifiMapper::parseDateAndTime>>    v string="+v.toString());
            
            OctetString oct = (OctetString)v;
    //        adapterlog.info("YYWifiMapper::parseDateAndTime>>    v hex="+ oct.toHexString());
            
            byte[] bts = oct.getValue();
            
            byte[] format_str = new byte[128];   //保存格式化过后的时间字符串
            int year;
            int month;
            int day;
            int hour;
            int minute;
            int second;
            int msecond;
            
    //        for(byte b:bts){
    //            adapterlog.info("YYWifiMapper::parseDateAndTime>>    bts:"+b);
    //        }
            year=bts[0]*256+256+bts[1];        //adapterlog.info("YYWifiMapper::parseDateAndTime>>    year:"+year);
     
            month=bts[2];
            day=bts[3];
            hour=bts[4];
            minute=bts[5];
            second=bts[6];
            msecond=bts[7];
            //以下为格式化字符串
            int index=3;
            int temp=year;
            for(; index>=0; index--){
                format_str[index]=(byte)(48+(temp-temp/10*10));
                temp/=10;
            } 
            
            format_str[4]='-';
            index=6;
            temp=month;
            for(; index>=5; index--){
                format_str[index]=(byte)(48+(temp-temp/10*10));
                temp/=10;
            }
     
            format_str[7]='-';
            index=9;
            temp=day;
            for(; index>=8; index--){
                format_str[index]=(byte)(48+(temp-temp/10*10));
                temp/=10;
            }
     
            format_str[10]=' ';
            index=12;
            temp=hour;
            for(; index>=11; index--){
                format_str[index]=(byte)(48+(temp-temp/10*10));
                temp/=10;
            }
     
            format_str[13]=':';
            index=15;
            temp=minute;
            for(; index>=14; index--){
                format_str[index]=(byte)(48+(temp-temp/10*10));
                temp/=10;
            }
     
            format_str[16]=':';
            index=18;
            temp=second;
            for(; index>=17; index--){
                format_str[index]=(byte)(48+(temp-temp/10*10));
                temp/=10;
            }
     
            
    //        format_str[19]='.';
    //        index=21;
    //        temp=msecond;
    //        for(; index>=20; index--){
    //            format_str[index]=(byte)(48+(temp-temp/10*10));
    //            temp/=10;
    //        }
    //
    //        format_str[22]=0;  
    //        adapterlog.info("YYWifiMapper::parseDateAndTime>>    format_str = " + new String(format_str));
            
            return new String(format_str);
        }
    }

     

    实际运行log如下(注意值为16进制):

    YYWifiMapper::parseDateAndTime>>  v=07:dc:09:17:11:01:1b:02:2b:08:00

    YYWifiMapper::parseDateAndTime>>  format_str = 2012-09-23 17:01:27

     

     

    处理年的时候稍有不同,因为年是由两个字节表示,所以要用高位字节乘256再加低位字节,处理语句为year=bts[0]*256+256+bts[1];标准的时间输出格式应该为YYYY-MM-DD HH:MM:SS形式。

     

    其实自己用计算器就能算出时间,很简单了。

    主要是年的计算byte是可以为负值,所以手动计算的公式:

    07*256 + dc = 07*256 + 220 = 2012年;或者07*256 + (256 + dc) = 07*256 + (256 + (-36)) = 2012年;

    09 = 09月

    17 = 23日

    11 = 17时

    01 = 01分

    1b = 27秒

  • 相关阅读:
    微信小程序入门教程之三:脚本编程
    微信小程序入门教程之四:API 使用
    微信小程序入门教程之一:初次上手
    JZ2440开发笔记(9)——位置无关代码设计【转】
    JZ2440开发笔记(8)——FCLK、HCLK和PCLK
    JZ2440开发笔记(7)——2440启动方式
    JZ2440开发笔记(6)——存储控制器
    JZ2440开发笔记(5)——通过按键点亮LED
    JZ2440开发笔记(4)——设置静态IP
    JZ2440开发笔记(3)——配置TFTP
  • 原文地址:https://www.cnblogs.com/liuyou/p/2699154.html
Copyright © 2011-2022 走看看