一、报文封装类

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 }
View Code

相关文章:

  • 2021-04-13
  • 2022-12-23
  • 2021-06-29
  • 2021-08-28
  • 2021-10-19
  • 2021-05-14
  • 2022-01-15
  • 2022-12-23
猜你喜欢
  • 2021-07-13
  • 2022-02-01
  • 2022-12-23
  • 2022-12-23
  • 2021-11-17
  • 2022-12-23
  • 2021-11-11
相关资源
相似解决方案