socket自定义数据格式转化二进制
来源:互联网 发布:python 2.x.msi 编辑:程序博客网 时间:2024/06/06 01:16
自定义数据格式的方案
一般传送的数据,肯定有消息类型,消息序列号,具体的自定义消息内容;
则可以先定义一个统一的格式:
prefix + packType(1) + seq(4) +[userData](标志性前缀+消息类型+序列号+自定义数据)
封装成byte[] 和解析数据过程
针对上面根据每种消息类型自定义的userData,可以这样定义格式:
[filedType + filedLength+ filedValue](字段类型标志+字段长度+字段值)
直接看例子
packData ()为打包消息
public class Utils { byte PACKET_PREFIX = '$'; int FILED_HEADER_LENGTH = 5;//因为filedType为byte + filedLength为int,所以字段前缀长度为5 int MAX_PACKET_LENGTH = 1024;//包大小 1k int INT_LENGTH = 4; /** * 封装报文 * 协议:prefix + packType(1) + seq(4) +[userData] * prefix 标志性前缀 * packType - 报文类型 * seq - 发送序列 * userData - 用户数据 * * @param seq * @param packType * @param userData * @return */ public static byte[] packData(int seq, byte packType, byte[] userData) { if (userData == null) { return null; } byte[] data = new byte[MAX_PACKET_LENGTH]; int offset = 0; // 打包数据头部 //add prefix data[offset++] = PACKET_PREFIX; //add msgType data[offset++] = packType; //add seq addInt(data, offset, seq); offset += INT_LENGTH; if (data.length < offset + userData.length) {//数组大小不够,则需要扩容 byte[] tmp = new byte[offset + userData.length]; System.arraycopy(data, 0, tmp, 0, offset); data = tmp; } System.arraycopy(userData, 0, data, offset, userData.length); offset += userData.length; byte[] result = new byte[offset]; System.arraycopy(data, 0, result, 0, offset); return result; } public static int bytesToInt(byte[] src, int offset) { if (src == null || src.length < offset || offset + SearchConst.INT_LENGTH > src.length) { return -1; } int sendSeq; sendSeq = src[offset++] & 0xFF; sendSeq |= (src[offset++] << 8) & 0xFF00; sendSeq |= (src[offset++] << 16) & 0xFF0000; sendSeq |= (src[offset++] << 24) & 0xFF000000; return sendSeq; } public static byte[] intToBytes(int value) { byte[] src = new byte[4]; src[0] = (byte) (value & 0xFF); src[1] = (byte) ((value >> 8) & 0xFF); src[2] = (byte) ((value >> 16) & 0xFF); src[3] = (byte) ((value >> 24) & 0xFF); return src; } public static void addInt(byte[] src, int offset, int value) { byte[] seqBytes = intToBytes(value); System.arraycopy(seqBytes, 0, src, offset, 4); } /** * [filedType + filedLength+ filedValue] * * @param src * @param filedBytes */ public static void addFiledBytes(byte[] src, int offset, byte[] filedBytes, byte fieldType) { src[offset++] = fieldType; Utils.addInt(src, offset, filedBytes.length); offset += INT_LENGTH; System.arraycopy(filedBytes, 0, src, offset, filedBytes.length); }
下面为自定义的数据DeviceData 如何和byte[] 相互转化
public class DeviceData extends BaseUserData { private static final byte FIELD_TYPE_DEVID = 0x31; private static final byte FIELD_TYPE_SERVICENAME = 0x32; private static final byte FIELD_TYPE_PKGNAME = 0x33; private static final byte FIELD_TYPE_FUNCTION = 0x34; private String devId;//设备id private String serviceName; private String pkgName; private int func;//功能位 public String getDevId() { return devId; } public void setDevId(String devId) { this.devId = devId; } public String getServiceName() { return serviceName; } public void setServiceName(String serviceName) { this.serviceName = serviceName; } public String getPkgName() { return pkgName; } public void setPkgName(String pkgName) { this.pkgName = pkgName; } public int getFunc() { return func; } public void setFunc(int func) { this.func = func; } /** * [filedType + filedLength+ filedValue] * * @param device * @return */ public static byte[] packDeviceData(DeviceData device) { if (device == null || device.getDevId() == null || device .getServiceName() == null || device.getPkgName() == null) { return null; } try { byte[] devIdBytes = device.getDevId().getBytes("UTF-8"); byte[] serviceNameBytes = device.getServiceName().getBytes("UTF-8"); byte[] pkgNameBytes = device.getPkgName().getBytes("UTF-8"); byte[] funcBytes = Utils.intToBytes(device.getFunc()); byte[] data = new byte[SearchConst.MAX_PACKET_LENGTH]; int offset = 0; //add devId Utils.addFiledBytes(data, offset, devIdBytes, FIELD_TYPE_DEVID); offset += FILED_HEADER_LENGTH + devIdBytes.length; //add serviceName Utils.addFiledBytes(data, offset, serviceNameBytes, FIELD_TYPE_SERVICENAME); offset += FILED_HEADER_LENGTH + serviceNameBytes.length; //add pkgName Utils.addFiledBytes(data, offset, pkgNameBytes, FIELD_TYPE_PKGNAME); offset += FILED_HEADER_LENGTH + pkgNameBytes.length; //add func Utils.addFiledBytes(data, offset, funcBytes, FIELD_TYPE_FUNCTION); byte[] result = new byte[data.length]; System.arraycopy(data, 0, result, 0, data.length); return result; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } public static DeviceData parseDeviceUserData(byte[] userData) { DeviceData device = new DeviceData(); if (userData.length < FILED_HEADER_LENGTH) { return null; } int offset = 0; while (offset + FILED_HEADER_LENGTH < userData.length) { byte dataType = userData[offset++]; int len = Utils.bytesToInt(userData, offset); offset += INT_LENGTH; if (len < 0 || len + offset > userData.length) { return null; } switch (dataType) { case FIELD_TYPE_DEVID: String devId = null; try { devId = new String(userData, offset, len, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } device.setDevId(devId); break; case FIELD_TYPE_SERVICENAME: String serviceName = null; try { serviceName = new String(userData, offset, len, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } device.setServiceName(serviceName); break; case FIELD_TYPE_PKGNAME: String pkgName = null; try { pkgName = new String(userData, offset, len, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } device.setPkgName(pkgName); break; case FIELD_TYPE_FUNCTION: int func = Utils.bytesToInt(userData, offset); if (func > 0) { device.setFunc(func); } break; default: } offset += len; } return device; } @Override public String toString() { return "DeviceData={ip=" + ip + ",port=" + port + ",devId=" + devId + ",serviceName=" + serviceName + ",pkgName=" + pkgName + ",func=" + func + "}"; }}
2 0
- socket自定义数据格式转化二进制
- wince json数据格式转化
- MXNet数据格式转化
- JSON数据格式转化
- 二进制转化
- 一个自定义备份数据格式
- 十六进制转化为二进制
- 二进制转化为十六进制
- 十进制转化为二进制
- Bitset (二进制转化)
- 十进制转化成二进制
- 二进制转化成十进制
- 十进制转化为二进制
- 二进制的转化
- 二进制的转化
- 负数转化为二进制
- 十进制转化为二进制
- 二进制转化成十进制
- 发的好地方根据您发的
- 面向对象思想
- identifier of an instance of com.you.hibernate.model.TStudentInfo was altered from 6 to 7
- 进程间通信——共享内存
- 开放才能进步!Angular和Wijmo一起走过的日子
- socket自定义数据格式转化二进制
- 二分查找
- HDU1023_Train Problem II_卡特兰数
- 解决AndroidStudio添加ProjectLibary后在编译时遇到的各种问题之解决方式索引(finished with non-zero exit value and so on...)
- 关于开发项目遇到的问题和错误
- IntelliJ Idea 常用快捷键列表
- PAT-B 1016. 部分A+B (15)
- 蓝桥杯——递归二:典型递归模型(2017.2.20)
- omnet++ Simulation terminated with exit code: -1073741819 的一个解决方案