Java与C#通过Byte[]字节数组实现消息传递,跨语言数据序列化

2018-01-07· 3324 次浏览
支持类型: byte、short、int、long、float、double、boolean、char、String、byte\[\] Java中的BitConverter :[http://baike.xsoftlab.net/view/1191.html](http://baike.xsoftlab.net/view/1191.html) Java代码 ```java package com.itshidu.io;   import java.nio.charset.Charset;   import com.itshidu.util.BitConverter;   /**  * 发送的请求数据  * 数据类型:String_255=0;String_65535=1;Int8=2;Int16=3;Int32=4;Int64=5;Float=6;Double=7;Boolean=8;Char=9;Byte[]=10;  * String类型数值最大65535字节(UTF8字符集,每个汉字3字节)  * @author Master.Xia  */ public class NetMessage{           public static byte[] Concat(byte[]... bs) {         int len = 0,idx=0;         for(byte[] b:bs)len+=b.length;         byte[] buffer = new byte[len];         for(byte[] b:bs) {             System.arraycopy(b,0, buffer, idx, b.length);             idx+=b.length;         }         return buffer;     }           public int code;     public Object[] data;     public byte[] GetBytes() {         byte[] buffer = BitConverter.GetBytes(code);         buffer = Concat(buffer,new byte[] {(byte)data.length});         for(int i=0;i<data.length;i++) {             if(data[i] instanceof String) {          //String                 byte[] typeBytes = null;                 byte[] lenBytes = null;                 byte[] strBytes=((String)data[i]).getBytes(Charset.forName("UTF-8"));                 if(strBytes.length<=255) {                     typeBytes = new byte[]{(byte)0};                     lenBytes=new byte[]{(byte)(strBytes.length-128)};                 }else if(strBytes.length<=65535) {                     typeBytes = new byte[]{(byte)1};                     lenBytes=BitConverter.GetBytes((short)(strBytes.length-32768));                 }else {                     throw new RuntimeException("String Byte Length Out of Bounds:"+strBytes.length);                 }                 buffer = Concat(buffer,typeBytes,lenBytes,strBytes);             }else if(data[i] instanceof Byte) {     //Int8                 byte[] typeBytes = new byte[]{(byte)2};                 byte[] dataBytes = new byte[]{(byte)data[i]};                 buffer = Concat(buffer,typeBytes,dataBytes);             }else if(data[i] instanceof Short) {    //Int16                 byte[] typeBytes = new byte[]{(byte)3};                 byte[] dataBytes=BitConverter.GetBytes((short)data[i]);                 buffer = Concat(buffer,typeBytes,dataBytes);             }else if(data[i] instanceof Integer) {  //Int32                 byte[] typeBytes = new byte[]{(byte)4};                 byte[] dataBytes=BitConverter.GetBytes((int)data[i]);                 buffer = Concat(buffer,typeBytes,dataBytes);             }else if(data[i] instanceof Long) {     //Int64                 byte[] typeBytes = new byte[]{(byte)5};                 byte[] dataBytes=BitConverter.GetBytes((long)data[i]);                 buffer = Concat(buffer,typeBytes,dataBytes);             }else if(data[i] instanceof Float) {    //Float                 byte[] typeBytes = new byte[]{(byte)6};                 byte[] dataBytes = BitConverter.GetBytes((float)data[i]);                 buffer = Concat(buffer,typeBytes,dataBytes);             }else if(data[i] instanceof Double) {   //Double                 byte[] typeBytes = new byte[]{(byte)7};                 byte[] dataBytes = BitConverter.GetBytes(Double.doubleToLongBits((double)data[i]));                 buffer = Concat(buffer,typeBytes,dataBytes);             }else if(data[i] instanceof Boolean) {  //Boolean                 byte[] typeBytes = new byte[]{(byte)8};                 byte[] dataBytes = new byte[]{(byte)(((boolean)data[i])? 1:0)};                 buffer = Concat(buffer,typeBytes,dataBytes);             }else if(data[i] instanceof Character) {//Char                 byte[] typeBytes = new byte[]{(byte)9};                 byte[] dataBytes = new String(new char[] {(char)data[i]}).getBytes(Charset.forName("UTF-8"));                 byte[] lenBytes = new byte[] { (byte)dataBytes.length };                 buffer = Concat(buffer,typeBytes,lenBytes,dataBytes);             }else if(data[i] instanceof byte[]&##124;&##124;data[i] instanceof Byte[]) {  //byte[]:&##124;Type:1byte&##124;DataLen:4byte&##124;Data&##124;                 byte[] typeBytes = new byte[]{(byte)10};                 byte[] dataBytes = null;                 if(data[i] instanceof Byte[]){                     Byte[] bs1 = (Byte[])data[i];                     dataBytes = new byte[bs1.length];                     for(int m=0;m<bs1.length;m++){                         dataBytes[m]=(byte)bs1[m];                     }                 }else {                     dataBytes = (byte[])data[i];                 }                 byte[] lenBytes=BitConverter.GetBytes(dataBytes.length);                 buffer = Concat(buffer,typeBytes,lenBytes,dataBytes);             }         }         return buffer;     }     public NetMessage(byte[] bytes){         this.code = BitConverter.ToInt32(bytes, 0);         int count = BitConverter.ByteToInt(bytes[4]);         int index = 5;         this.data = new Object[count];         for(int i=0;i<count;i++) {             int argType = BitConverter.ByteToInt(bytes[index++]);             if(argType==0) { //String_256                 int len = BitConverter.ByteToInt((byte)(128+bytes[index++]));                 data[i] = new String(bytes,index,len,Charset.forName("UTF-8"));                 index += len;             }else if(argType==1) { //String_65535                 int len = BitConverter.ToInt16(bytes, index)+32768;                 index += 2;                 data[i] = new String(bytes,index,len,Charset.forName("UTF-8"));                 index += len;             }else if(argType==2) { //Byte                 data[i] = BitConverter.ByteToInt(bytes[index++]);             }else if(argType==3) { //Short                 data[i] = BitConverter.ToInt16(bytes, index);                 index += 2;             }else if(argType==4) { //Int                 data[i] = BitConverter.ToInt32(bytes, index);                 index += 4;             }else if(argType==5) { //Long                 data[i] = BitConverter.ToInt64(bytes, index);                 index += 8;             }else if(argType==6) { //Float                 data[i] = BitConverter.ToFloat(bytes, index);                 index += 4;             }else if(argType==7) { //Double                 data[i] = Double.longBitsToDouble(BitConverter.ToInt64(bytes, index));                 index+=8;             }else if(argType==8) { //Boolean                 data[i]=(bytes[index++]==0x00)? false:true;             }else if(argType==9) { //Char                 Charset charset = Charset.forName("UTF-8");                 int len = BitConverter.ByteToInt(bytes[index++]);                 data[i] = new String(bytes,index,len,charset).toCharArray()[0];                 index += len;             }else if(argType==10) { //Byte[]                 int len6 = BitConverter.ToInt32(bytes, index);                 index += 4;                 data[i] = new byte[len6];                 System.arraycopy(bytes, index, data[i], 0, len6);                 index += len6;             }else {                 System.out.println("无法识别的类型码:"+argType);             }                       }     }     public byte[] pack() {         byte[] dataBytes = this.GetBytes();         byte[] lenBytes = BitConverter.GetBytes(dataBytes.length);         return Concat(lenBytes,dataBytes);     }           public NetMessage(int code,Object...objects) {         this.code = code;         this.data = objects;     }     public NetMessage(int code) {         this.code = code;     }           public static void main(String[] args) {         NetMessage a = new NetMessage(                 12,(byte)100,(short)1000,(int)10000,(long)100000,1.414f,3.141592654,true,false,'@','哈'                 ,"HelloWorld".getBytes()                 ,"中华人民共和国万岁".getBytes()                 ,123                 );                   byte[] bs = a.GetBytes();         NetMessage b = new NetMessage(bs);         System.out.println(b.code);         for(Object o : b.data) {             System.out.println(o);         }         System.out.println(new String((byte[])b.data[b.data.length-2]));     }             } ``` C#代码 ```cs using System; using System.Collections; using System.Collections.Generic; using System.Text;   namespace com.itshidu.io {     public class NetMessage {         public int code;         public object[] data;         private int ByteToInt(byte b) {             return b & 0xFF;         }         public static byte[] Concat(params byte[][] arrays) {             int total = 0;             foreach (byte[] bs in arrays) {                 total += bs.Length;             }             byte[] buffer = new byte[total];             int index = 0;             foreach (byte[] bs in arrays) {                 bs.CopyTo(buffer, index);                 index += bs.Length;             }             return buffer;         }         public static byte[] LongToBytes(long values) {             byte[] buffer = new byte[8];             for (int i = 0; i < 8; i++) {                 int offset = 64 - (i + 1) * 8;                 buffer[i] = (byte)((values >> offset) & 0xff);             }             return buffer;         }           public static long BytesToLong(byte[] buffer,int offset) {             long values = 0;             for (int i = 0; i < 8; i++) {                 values <<= 8;                 values &##124;= (byte)(buffer[offset+i] & 0xFF);             }             return values;         }         public NetMessage(byte[] bytes, int offset, int len) {             byte[] buffer = new byte[len];             Array.Copy(bytes, offset, buffer, 0, len);             Parse(buffer);         }         public NetMessage(byte[] bytes) {             Parse(bytes);         }         public NetMessage(int code, params object[] objects) {             this.code = code;             this.data = objects;         }           public void Parse(byte[] bytes) {             this.code = BitConverter.ToInt32(bytes, 0);             int count = bytes[4] & 0xFF;             int index = 5;             this.data = new object[count];             for (int i = 0; i < count; i++) {                 int argType = bytes[index++] & 0xFF;                 if (argType == 0) { //String_255                     int len = ByteToInt((byte)(128 + bytes[index++]));                     data[i] = Encoding.UTF8.GetString(bytes, index, len);                     index += len;                 } else if (argType == 1) { //String_65535                     int len = BitConverter.ToInt16(bytes, index)+ 32768;                     index += 2;                     data[i] = Encoding.UTF8.GetString(bytes, index, len);                     index += len;                 } else if (argType == 2) { //Byte                     data[i] = ByteToInt(bytes[index++]);                 } else if (argType == 3) { //Short                     data[i] = BitConverter.ToInt16(bytes, index);                     index += 2;                 } else if (argType == 4) { //Int                     data[i] = BitConverter.ToInt32(bytes, index);                     index += 4;                 } else if (argType == 5) { //Long                     data[i] = BytesToLong(bytes, index);                     index += 8;                 } else if (argType == 6) { //Float                     data[i] = BitConverter.ToSingle(bytes, index);                     index += 4;                 } else if (argType == 7) { //Double                     data[i] = BitConverter.Int64BitsToDouble(BytesToLong(bytes, index));                     index += 8;                 } else if (argType == 8) { //Boolean                     data[i] = (bytes[index++] == 0x00) ? false : true;                 } else if (argType == 9) { //Char                     int len = ByteToInt(bytes[index++]);                     data[i] = Encoding.UTF8.GetChars(bytes, index, len)[0];                     index += len;                 } else if (argType == 10) { //Byte[]                     int len6 = BitConverter.ToInt32(bytes, index);                     index += 4;                     byte[] buf = new byte[len6];                     data[i] = buf;                     Array.Copy(bytes, index, buf, 0, len6);                     index += len6;                 } else {                     Console.WriteLine("无法识别的类型码:" + argType);                 }             }         }             public byte[] GetBytes() {             byte[] buffer = BitConverter.GetBytes(code);             buffer = Concat(buffer, new byte[] { (byte)data.Length });             for (int i = 0; i < data.Length; i++) {                 if (data[i].GetType() == typeof(string)) {  //String                     byte[] typeBytes = null;                     byte[] lenBytes = null;                     byte[] strBytes = Encoding.UTF8.GetBytes((string)data[i]);                     if (strBytes.Length <= 255) {                         typeBytes = new byte[] { (byte)0 }; //String_255                         lenBytes = new byte[] { (byte)(strBytes.Length - 128) };                     } else if (strBytes.Length <= 65535) {                         typeBytes = new byte[] { (byte)1 }; //String_65535                         lenBytes = BitConverter.GetBytes((short)(strBytes.Length - 32768));                     }                     buffer = Concat(buffer, typeBytes, lenBytes, strBytes);                 } else if (data[i].GetType() == typeof(byte)) {      //Int8                     byte[] typeBytes = new byte[] { (byte)2 };                     byte[] dataBytes = new byte[] { (byte)data[i] };                     buffer = Concat(buffer, typeBytes, dataBytes);                 }else if (data[i].GetType() == typeof(short)) { //Int16                     byte[] typeBytes = new byte[] { (byte)3 };                     byte[] dataBytes = BitConverter.GetBytes((short)data[i]);                     buffer = Concat(buffer, typeBytes, dataBytes);                 }else if (data[i].GetType() == typeof(int)) {   //Int32                     byte[] typeBytes = new byte[] { (byte)4 };                     byte[] dataBytes = BitConverter.GetBytes((int)data[i]);                     buffer = Concat(buffer, typeBytes, dataBytes);                 }else if (data[i].GetType() == typeof(long)) {  //Int64                     byte[] typeBytes = new byte[] { (byte)5 };                         byte[] dataBytes = LongToBytes((long)data[i]);                     buffer = Concat(buffer, typeBytes, dataBytes);                 }else if (data[i].GetType() == typeof(float)) { //Float                     byte[] typeBytes = new byte[] { (byte)6 };                     byte[] dataBytes = BitConverter.GetBytes((float)data[i]);                     buffer = Concat(buffer, typeBytes, dataBytes);                 }else if (data[i].GetType() == typeof(double)) {//Double                     byte[] typeBytes = new byte[] { (byte)7 };                         byte[] dataBytes=LongToBytes(BitConverter.DoubleToInt64Bits((double)data[i]));                         buffer = Concat(buffer, typeBytes,dataBytes);                     } else if (data[i].GetType() == typeof(bool)) {   //Boolean                     byte[] typeBytes = new byte[] { (byte)8 };                     byte[] dataBytes = new byte[] { (byte)(((bool)data[i]) ? 1 : 0) };                     buffer = Concat(buffer, typeBytes, dataBytes);                 }else if (data[i].GetType() == typeof(char)) {//Char                     byte[] typeBytes = new byte[] { (byte)9 };                     byte[] dataBytes = Encoding.UTF8.GetBytes(new char[] { (char)data[i] });                     byte[] lenBytes = new byte[] { (byte)dataBytes.Length };                     buffer = Concat(buffer, typeBytes,lenBytes,dataBytes);                 }else if (data[i].GetType() == typeof(byte[])) {    //byte[]:&##124;Type:1byte&##124;DataLen:4byte&##124;Data&##124;                     byte[] typeBytes = new byte[] { (byte)10 };                     byte[] dataBytes = (byte[])data[i];                     byte[] lenBytes = BitConverter.GetBytes(dataBytes.Length);                     buffer = Concat(buffer, typeBytes, lenBytes, dataBytes);                 }             }             return buffer;         }         public byte[] pack() {                 byte[] msgBytes = this.GetBytes();                 byte[] lenBytes = BitConverter.GetBytes(msgBytes.Length);                 return NetMessage.Concat(lenBytes, msgBytes);             }         } } ```