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); } } }
相關推薦
Java與C#通過Byte[]位元組陣列實現訊息傳遞,跨語言資料序列化
支援型別: byte、short、int、long、float、double、boolean、char、String、byte[] Java程式碼 package com.itshidu.io; import java.nio.charset.Charset;
關於Java與c++隱藏、重寫不同實現機制的探討
tail namespace 文獻 ide archive pretty proc font 分開 一、文章來由 本人如今用c++很多其它。可是曾經Java也寫過不少,Java和c++非常像,可是深入挖一些,Java跟c++的差別非常大,就拿剛剛發的另
Java與C通過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實現JAVA與C/C++程式間的呼叫和回撥
在一些Android應用的開發中,需要通過JNI和 Android NDK工具實現JAVA和C/C++之間的相互呼叫。 Java Native Interface (JNI)標準是java平臺的一部分,它允許Java程式碼和其他語言寫的程式碼進行
如何一步步實現JAVA與C# 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樹到紅黑樹(下) Java與C的實現
歡迎探討,如有錯誤敬請指正 相關部落格: 1. 實現技巧 為了簡化程式碼和減少不必要的開銷,在具體的實現中我們定義一個偽根節點ROOT且只定義一個NIL節點。偽根節點的左子支永遠指向NIL節點,NIL節點的左右子支又指向它自身。偽根節點的右子支才表示真正的紅黑樹。 2. Java語言實現 packa
php字串與byte位元組陣列轉化類示例
<?php /** * byte陣列與字串轉化類 */class Bytes { /** * 轉換一個String字串為byte陣列 * @param $str 需要轉換的字串 * @param $bytes 目標byte陣列 * @author Zikie */
java與C/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
java與c#使用Socket實現區域網聊天
先執行一個java寫的區域網聊天,效果圖如下 後使用c#圖形修改如下: c#程式碼: servlet服務端 using System; using System.Collections.Generic; using System.Drawing; using Sys
JAVA與C++,C與C++的差別
-m content 才幹 hit 沒有 span 自增 ng- data- 首先來分析JAVA與C++的差別: JAVA是純面向對象的語言,而C++是基於面向對象過程的語言。 JAVA有著垃圾回收機制。它的語法是C+
Java與C++語法的區別
有變 程序 mda 一次 高層 修飾 int 屬性 代碼 1. 註釋可以在Java程序中起到文檔標記的作用 類文檔標記: 1)@version 2)@author 3)@param 4)@return 5)@exception 2. Java的字符占兩個
隨筆④ java與c ++/c比較
可能 隨筆 pan ont -s size 內存 span 關心 Java和C/C++的比較 Java不支持指針,C/C++支持 Java程序不需要顯式地關心內存釋放,而C/C++需要 Java程序需要編譯成字節碼文件,然後再解釋執行。 Java數組可能溢出,C/C++數
[工作小記]JAVA與C#的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