一、报文封装类
AbstractPortalMsg.java
Portal协议数据报文封装类
1 package org.yoki.edu.common.protocol.portal.msg; 2 3 import lombok.Data; 4 import lombok.ToString; 5 import org.yoki.edu.common.protocol.portal.msg.attr.MsgAttr; 6 7 import java.util.ArrayList; 8 import java.util.List; 9 10 /** 11 * Portal协议数据报文封装类 12 * 13 * @author Sky$ 14 * @Description: TODO 15 * @date 2017/10/24$ 19:16$ 16 */ 17 @Data 18 @ToString 19 public abstract class AbstractPortalMsg { 20 21 protected int ver; 22 protected int type; 23 protected int papChap = 1; 24 protected int rsvd = 0; 25 protected int serialNo; 26 protected int reqId; 27 protected String userIp; 28 protected int userPort = 0; 29 protected int errCode; 30 protected int attrNum; 31 /** 32 * 属性列表 33 */ 34 protected List<MsgAttr> attrList = new ArrayList<>(); 35 36 /** 37 * 添加属性的方法 38 * 39 * @param attr 40 * @return 41 */ 42 public List<MsgAttr> addMsgAttr(MsgAttr attr) { 43 if (null == attrList) { 44 attrList = new ArrayList<>(); 45 } 46 attrList.add(attr); 47 return attrList; 48 } 49 50 51 /** 52 * 将hander部分的字段转化为16个字节 53 * 54 * @return 55 */ 56 protected byte[] getHander16Bytes() { 57 byte[] b = new byte[16]; 58 b[0] = (byte) (ver & 0xff); 59 b[1] = (byte) (type & 0xff); 60 b[2] = (byte) (papChap & 0xff); 61 b[3] = (byte) (rsvd & 0xff); 62 b[4] = (byte) (serialNo >> 8 & 0xff); 63 b[5] = (byte) (serialNo & 0xff); 64 b[6] = (byte) (reqId >> 8 & 0xff); 65 b[7] = (byte) (reqId & 0xff); 66 byte[] ip = ipv4Address2BinaryArray(userIp); 67 System.arraycopy(ip, 0, b, 8, 4); 68 b[12] = (byte) (userPort >> 8 & 0xff); 69 b[13] = (byte) (userPort & 0xff); 70 b[14] = (byte) (errCode & 0xff); 71 b[15] = (byte) (attrNum & 0xff); 72 return b; 73 } 74 75 /** 76 * 将属性列表转化为字节数组 77 * 78 * @return 79 */ 80 protected byte[] getAttrBytes() { 81 int attrByteNum = 0; 82 if (attrList != null && !attrList.isEmpty()) { 83 for (MsgAttr a : attrList) { 84 attrByteNum += a.getAttrLen(); 85 } 86 } 87 byte[] b = new byte[attrByteNum]; 88 int index = 0; 89 if (attrList != null && !attrList.isEmpty()) { 90 for (MsgAttr a : attrList) { 91 System.arraycopy(a.getByteValues(), 0, b, index, a.getByteValues().length); 92 index += a.getByteValues().length; 93 } 94 } 95 return b; 96 } 97 98 /** 99 * 抽象方法:获取该报文类的字节数组<br> 100 * 抽象出该方法是因为移动Portal和华为Portal协议有些区别<br> 101 * 华为Portal有一个MD5加密字段 102 * 103 * @return 104 */ 105 public abstract byte[] toByteArray(); 106 107 /** 108 * 抽象方法:通过报文字节数组,解析出各个字段值,并赋值<br> 109 * 抽象出该方法是因为移动Portal和华为Portal协议有些区别<br> 110 * 华为Portal有一个MD5加密字段 111 * 112 * @param input Portal协议报文字节数组 113 */ 114 public abstract void parse(byte[] input); 115 116 /** 117 * 通过报文字节数组,解析出header部分的信息,并赋值 118 * 119 * @param input Portal协议报文字节数组 120 */ 121 protected void parseHeader(byte[] input) { 122 this.setVer(input[0]); 123 this.setType(input[1]); 124 this.setPapChap(input[2]); 125 this.setRsvd(input[3]); 126 127 this.setSerialNo(((0xff & input[4]) << 8) | (0xff & input[5])); 128 this.setReqId(((0xff & input[6]) << 8) | (0xff & input[7])); 129 130 this.setUserIp((input[8] & 0xff) + "." + (input[9] & 0xff) + "." + (input[10] & 0xff) + "." + (input[11] & 0xff)); 131 this.setUserPort(((0xff & input[12]) << 8) | (0xff & input[13])); 132 133 this.setErrCode(0xff & input[14]); 134 this.setAttrNum(0xff & input[15]); 135 } 136 137 /** 138 * 通过报文字节数组,解析出attr部分的信息,并赋值 139 * 140 * @param attrBytes attr数组的字节数组 141 * @param attrNum attr的个数 142 */ 143 protected void parseAttr(byte[] attrBytes, int attrNum) { 144 List<MsgAttr> attrList = new ArrayList<MsgAttr>(); 145 int count = attrNum; 146 if (count > 0) { 147 int t = 0; 148 for (int i = 0; i < count; i++) { 149 int attrType = attrBytes[t]; 150 int attrLen = attrBytes[t + 1]; 151 byte[] d = new byte[attrLen - 2]; 152 System.arraycopy(attrBytes, t + 2, d, 0, attrLen - 2); 153 MsgAttr c = new MsgAttr(attrType, new String(d)); 154 attrList.add(c); 155 t += c.getAttrLen(); 156 } 157 } 158 this.setAttrList(attrList); 159 } 160 161 /** 162 * IP地址转换工具方法,将IP字符串转换为字节数组 163 * 164 * @param ipAdd 165 * @return 166 */ 167 protected byte[] ipv4Address2BinaryArray(String ipAdd) { 168 byte[] binIP = new byte[4]; 169 String[] strs = ipAdd.split("\\."); 170 for (int i = 0; i < strs.length; i++) { 171 binIP[i] = (byte) Integer.parseInt(strs[i]); 172 } 173 return binIP; 174 } 175 176 177 }