1. 程式人生 > >Java與C#通過Byte[]位元組陣列實現訊息傳遞,跨語言資料序列化

Java與C#通過Byte[]位元組陣列實現訊息傳遞,跨語言資料序列化

支援型別:

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

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);
            }
        }
}

相關推薦

JavaC#通過Byte[]位元組陣列實現訊息傳遞語言資料序列

支援型別: byte、short、int、long、float、double、boolean、char、String、byte[] Java程式碼 package com.itshidu.io; import java.nio.charset.Charset;

關於Javac++隱藏、重寫不同實現機制的探討

tail namespace 文獻 ide archive pretty proc font 分開 一、文章來由 本人如今用c++很多其它。可是曾經Java也寫過不少,Java和c++非常像,可是深入挖一些,Java跟c++的差別非常大,就拿剛剛發的另

JavaC通過JNI指標相互傳遞

轉載地址: http://blog.csdn.net/neo_86/article/details/24931509 注意 1、c中指標可以直接轉為java裡的int值,都是32位無損失(32位作業系統或者gcc 32編譯器)。 2、迴圈裡要注意釋放本地引用,因為迴圈太

將圖片通過byte[]位元組陣列Base64加密後給前端顯示

1.base64編碼顯示圖片 一般我們後臺給前端傳圖片,有兩種方式,一種就是通過response.getOutputStream直接將圖片以流的形式寫到頁面顯示,另一種就是先把圖片上傳到伺服器,拿到url地址後把url地址給前端 第一種方式簡單,不需要伺服器

Google Protobuf——實現跨平臺語言序列/反序列

Google Protobuf——實現跨平臺跨語言的序列化/反序列化 0 Overview Google Protocol Buffer 是一個平臺無關、語言無關的結構化資料的序列化與反序列化工具。 1 Establish dev environment wget http:

Android開發 通過JNI實現JAVAC/C++程式間的呼叫和回撥

       在一些Android應用的開發中,需要通過JNI和 Android NDK工具實現JAVA和C/C++之間的相互呼叫。        Java Native Interface (JNI)標準是java平臺的一部分,它允許Java程式碼和其他語言寫的程式碼進行

如何一步步實現JAVAC# AES加密結果相同

實現JAVA與C# AES加密結果相同 最近公司開發一個電池溯源的介面,對方給的是一個java的demo,使用的是AES加密,但是我們的整合平臺是使用C#開發的,所有必須把java中的AES加密方法改成C#實現。對方給的demo如下 /**

java String包裝類和位元組陣列、字元陣列間的轉換

java String與包裝類和位元組陣列、字元陣列間的轉換 1. 字串與基本資料的相互轉化 2.字串與字元、位元組陣列之間的轉換 1.字串轉換成字元陣列 2. 位元組陣列轉換成字串

C# 常見的位元組陣列 byte[] 複製方法

byte[] src ={1,2,3,4,5}; byte[] dest = new byte[src.Length]; for(int i=0; i<src.Length; i++) { dest[i] = src[i] } byte[] src ={1,2,3,4,5}; by

從2-3-4樹到紅黑樹(下) JavaC實現

歡迎探討,如有錯誤敬請指正 相關部落格: 1. 實現技巧 為了簡化程式碼和減少不必要的開銷,在具體的實現中我們定義一個偽根節點ROOT且只定義一個NIL節點。偽根節點的左子支永遠指向NIL節點,NIL節點的左右子支又指向它自身。偽根節點的右子支才表示真正的紅黑樹。 2. Java語言實現 packa

php字串byte位元組陣列轉化類示例

<?php /** * byte陣列與字串轉化類 */class Bytes { /** * 轉換一個String字串為byte陣列 * @param $str 需要轉換的字串 * @param $bytes 目標byte陣列 * @author Zikie */  

javaC/C++之間通過jni相互呼叫

一、jni簡介: 企業應用 JNI一直以來都很少去關注,但卻是我心中的一個結,最近這幾天剛好手頭有點時間,因此抽空看了一下這方面的東西,整理了一份文件,JNI技術的出現主要是基於三個方面的應用需求: 1. 解決效能問題 Java具有平臺

C# 三種位元組陣列(byte[])拼接的效能對比測試

之前做的通訊框架,一直用的List<byte>做的資料接收池。今天有點閒暇時間,特地寫了個DEMO將C#中的三種位元組陣列拼接方式的效能做了一個對比測試。 程式碼如下(若程式碼有不嚴謹或錯誤之處,懇請指出。): using System; using Syst

Java byte[] 位元組陣列 轉 二進位制 八進位制 十進位制 十六進位制字串

【前言】 java中很多時候需要將byte[]轉為各種進位制的字串顯示,從2,8,10,16到比較高階的base64(編碼), 至於什麼時候需要這樣,當你遇到這樣的問題就知道了。 【程式碼】 進位制轉換比較簡單,直接上程式碼,編碼轉換見其他文章。例如這個 package

javac#使用Socket實現區域網聊天

先執行一個java寫的區域網聊天,效果圖如下 後使用c#圖形修改如下: c#程式碼: servlet服務端 using System; using System.Collections.Generic; using System.Drawing; using Sys

JAVAC++,CC++的差別

-m content 才幹 hit 沒有 span 自增 ng- data- 首先來分析JAVA與C++的差別: JAVA是純面向對象的語言,而C++是基於面向對象過程的語言。 JAVA有著垃圾回收機制。它的語法是C+&#

JavaC++語法的區別

有變 程序 mda 一次 高層 修飾 int 屬性 代碼 1. 註釋可以在Java程序中起到文檔標記的作用 類文檔標記: 1)@version 2)@author 3)@param 4)@return 5)@exception 2. Java的字符占兩個

隨筆④ javac ++/c比較

可能 隨筆 pan ont -s size 內存 span 關心 Java和C/C++的比較 Java不支持指針,C/C++支持 Java程序不需要顯式地關心內存釋放,而C/C++需要 Java程序需要編譯成字節碼文件,然後再解釋執行。 Java數組可能溢出,C/C++數

[工作小記]JAVAC#的Socket通信

motion pmo sleep ddr trace ktr 不同的 ram target 在日常的開發中,不同的傳感器支持的開發語言常常是不同的。例如Kinect一般是用C++開發的,Leapmotion用JAVA開發比較多。 去年暑假(17年暑假)做的一個項目是:用Le

C# 通過各個函數實現控制臺日歷

tex 年總 summary lda 月的天數 clas tostring pac urn using System; using System.Collections.Generic; using System.Linq; using System.Text; nam