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

支持类型:

byte、short、int、long、float、double、boolean、char、String、byte[]

Java中的BitConverter :http://baike.xsoftlab.net/view/1191.html

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[]||data[i] instanceof Byte[]) {  //byte[]:|Type:1byte|DataLen:4byte|Data|
                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#代码

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 |= (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[]:|Type:1byte|DataLen:4byte|Data|
                    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);
            }
        }
}

猜你喜欢

转载自blog.csdn.net/qq_31967569/article/details/81166504