snmp4j 中的中文字符输出问题

来源:互联网 发布:捕鱼软件有用吗 编辑:程序博客网 时间:2024/06/07 08:46

snmp4j 中的中文字符输出问题, 不在于解码,而在于输出。

 

在使用snmp4j 通过 ip 和 OID来获取 snmp代理的 网络接口描述时, 在snmp4j-1.11.1上测试,当遇到中文或者编码值大于 0x80 的字符时,就会直接以十六机制数给出,并且给出的十六机制数是通过与 0xff 做 & 运算的值,比如说: response中包含字符的十六机制表示是:

0xffffffda(32位), 就会输出 0Xda, 其实查看snmp4j的源代码,snmp send request的同时获取的response的 PDU 都会通过 BER 来解码(主要研究了一下 decodeString), 可以跟中response 给出的 PDUInputstream 的值,通过输出byte数组(如New String(Byte[]))输出都是正常的32位置和对应的正确的编码显示:

 

其实同snmp++ 一样,是在输出字符的时候,在

package org.snmp4j.smi 中包含的 class OctetString.java 在输出结果转换成字符窜的时候回调用

 

public String toString() {

    if (isPrintable()) {                    // 见下面的 isPrintable() 方法

      return new String(value);

    }

    return toHexString();                 // Hex 输出

  }

 

 

/*  如果想要输出中文,直接将 if 语句注释即可解决 */

/**

   * Determines whether this octet string contains non ISO control characters

   * only.

   * @return

   *    <code>false</code> if this octet string contains any ISO control

   *    characters as defined by <code>Character.isISOControl(char)</code>

   *    except if these ISO control characters are all whitespace characters

   *    as defined by <code>Character.isWhitespace(char)</code>.

   */

  public boolean isPrintable() {

    for (int i=0; i<value.length; i++) {

      char c = (char)value[i];

      if ((Character.isISOControl(c) ||

          ((value[i] & 0xFF) >= 0x80)) && (!Character.isWhitespace(c))) {     //  (value[i] & 0xFF) >= 0x80)

        return false;

      }

    }

    return true;

  }

 

/*  Source code 中可以查看到 toHexString 会调用到下面的toString方法,语句 value[i] & 0xFF 是输出结果为被截取的十六进制数的原因 */

public String toString(char separator, int radix) {

    int digits = (int)(Math.round((float)Math.log(256)/Math.log(radix)));

    StringBuffer buf = new StringBuffer(value.length*(digits+1));

    for (int i=0; i<value.length; i++) {

      if (i > 0) {

        buf.append(separator);

      }

      int v = (value[i] & 0xFF);

      String val = Integer.toString(v, radix);

      for (int j=0; j < digits - val.length(); j++) {

        buf.append('0');

      }

      buf.append(val);

    }

    return buf.toString();

  }

 

至于为什么snmp4j 的设计是出于什么目的要屏蔽掉对于 大于 0Xff 的字符的输出的原因 可能是因为 snmp 获取的信息大都是英文,如此可以节省输出时的空间,还是有其他原因,还不得而知,现在想的是这样的改变输出 其他 字符 会不会带来其他的副作用。