⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avppacket.java

📁 AVP三元组协议包
💻 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 + -