📄 avppacket.java
字号:
package com.transfar.iios.tsapi.protocol;
import java.io.InputStream;
import java.net.DatagramPacket;
import java.util.Enumeration;
import java.util.Hashtable;
/**
* <p>Title: AvpPacket类</p>
* <p>Description: 三元组协议包类型</p>
* <p>(C)Copyright,2007,2008</p>
* <p>Company: Transfar&Timeson</p>
* @author wezly
* @version 1.8
*/
public class AvpPacket {
// 包的类型
private byte TYPE;
// 整个包(包括包头)的大小
private short SIZE;
// 流水号,从0-255循环
private byte SN;
// MD5(TYPE,SIZE,SN,DATA项内容+ Shared_secret),
// shared_secret是双方约定的信用凭证
private byte[] CHECKSUM;
// 每项数据采用属性ID|长度|内容三元组形式.
// 属性ID作为Hashtable的key,相应属性ID的值作为Hashtable的key的值
private Hashtable DATA;
private boolean isValid;
/**
* 功能:AvpPacket类带参数的构造函数
* @param byteArr 用来构造AVP包的字节数组
*/
public AvpPacket(byte[] byteArr) {
if(byteArr==null){
this.isValid = false;
}
TYPE = byteArr[0];
switch (TYPE) {
case 101:
case 102:
case 103:
case 104:
case 105:
case 106:
this.isValid = true;
break;
default:
this.isValid = false;
}
SIZE = (short) (((byteArr[1] & 0xFF) << 8) + (byteArr[2] & 0xFF));
SN = byteArr[3];
CHECKSUM = new byte[16];
for (int i = 0; i < 16; i++) {
CHECKSUM[i] = byteArr[i + 4];
}
DATA = new Hashtable();
for (int i = 20; i < SIZE; i += ((byteArr[i + 1] & 0xFF))) {
int valueID = byteArr[i];
int valueLenth = (byteArr[i + 1] & 0xFF) - 2;
byte[] valueByteArr = new byte[valueLenth];
for (int j = 0; j < valueLenth; j++) {
valueByteArr[j] = byteArr[j + i + 2];
}
DATA.put(new Integer(valueID), new String(valueByteArr));
}
}
/**
* 功能:根据包实例信息,生成相应的byte[]数据结构
* @return AVP包实例的字节数组形式
*/
public byte[] getBytes() {
byte[] tmpByte = new byte[4096];
tmpByte[0] = this.TYPE;
tmpByte[3] = this.SN;
Enumeration en = this.DATA.keys();
// 包头为固定的20个字节,因此取数据包内容去20字节开始
// 偏移,逐个遍历复制到字节数组
short offset = 20;
// 用Enumeration接口方法遍历哈希表中key,即属性ID
while (en.hasMoreElements()) {
Integer valueID = (Integer) en.nextElement();
tmpByte[offset] = valueID.byteValue();
offset++;
String valueStr = (String) this.DATA.get(valueID);
byte[] valueByteArr = valueStr.getBytes();
tmpByte[offset] = (byte) (valueByteArr.length+2);
offset++;
for (int i = 0; i < valueByteArr.length; i++) {
tmpByte[offset + i] = valueByteArr[i];
}
offset += valueByteArr.length;
}
// 包的大小,要用网络字节顺序,即大端表示法(Big-Endian)
//tmpByte[1] = (byte) (byte) (((offset & 0xff00) >> 8));
tmpByte[1] = (byte) (offset >>> 8);
tmpByte[2] = (byte) (offset & 0xff);
//TODO AVP包CHECK-SUM段填设置
//tmpByte[4]~tmpByte[19]
byte[] retByte = new byte[offset];
for(int i=0; i<offset; i++)
retByte[i] = tmpByte[i];
return retByte;
}
/**
* 功能:根据包类型、包流水号、数据项哈希表构造AVP数据包
* @param type 包类型,如:101代表新建数据请求包,102代表新建数据请求包响应;
* 103修改数据请求包,104代表修改数据请求响应包
* @param sn 流水号
* @param hashTb 数据内容
* @return 字节数组形式的AVP数据包
*/
public static byte[] avpBuilder(byte type, byte sn, Hashtable hashTb) {
byte[] tmpByte = new byte[4096];
tmpByte[0] = type;
tmpByte[3] = sn;
Enumeration en = hashTb.keys();
// 包头为固定的20个字节,因此取数据包内容从第20字节
// 开始偏移,逐个遍历赋值到字节数组中
short offset = 20;
// 用Enumeration接口方法遍历哈希表中key,即属性ID
while (en.hasMoreElements()) {
Integer valueID = (Integer) en.nextElement();
tmpByte[offset] = valueID.byteValue();
offset++;
String valueStr = (String) hashTb.get(valueID);
byte[] valueByteArr = valueStr.getBytes();
tmpByte[offset] = (byte) (valueByteArr.length + 2);
offset++;
for (int i = 0; i < valueByteArr.length; i++) {
tmpByte[offset + i] = valueByteArr[i];
}
offset += valueByteArr.length;
}
// 包的大小,用网络字节顺序,即大端表示法(Big-Endian)
//tmpByte[1] = (byte) (byte) (((offset & 0xff00) >> 8));
tmpByte[1] = (byte) (offset >>> 8);
tmpByte[2] = (byte) (offset & 0xff);
//TODO AVP包CHECK-SUM段填设置
//tmpByte[4]~tmpByte[19]
byte[] retByte = new byte[offset];
for(int i=0; i<offset; i++)
retByte[i] = tmpByte[i];
return retByte;
}
public AvpPacket(DatagramPacket dgrmPack) {
this(dgrmPack.getData());
}
public AvpPacket(InputStream is) {
//TODO 以流方式构造AVP对象
}
public Hashtable getData() {
return DATA;
}
public byte getTYPE() {
return TYPE;
}
public byte getSN() {
return SN;
}
public boolean isValid() {
return isValid;
}
public short getSIZE() {
return SIZE;
}
public static void main(String[] args) {
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -