先交待一下業務應用背景:
服務端:移動交費系統:基於C語言的Unix系統
客戶端:增值服務系統:基於Java的軟件系統
通迅協議:採用TCP/IP協議,使用TCP以異步方式接入
數據傳輸:基於Socket流的方式,傳輸的是網絡字節序
Java Socket通訊實現方式這裏不做過多的描述,網上到處可以搜索到,比較簡單,這裏要說的是Java 與 C 進行Socket通訊需注意的地方:
1、Java與C的各種數據類型存儲的字節數是不同的:
Java與C的數據類型的比較
Type Java C
short 2-Byte 2-Byte
int 4-Byte 4-Byte
long 8-Byte 4-Byte
float 4-Byte 4-Byte
double 8-Byte 8-Byte
boolean 1-bit N/A
byte 1-Byte N/A
char 2-Byte 1-Byte
所以在通訊前,需要進行類型轉換,對於C定義的unsign char爲一個字節存儲,對應Java這邊用byte存儲;對於C定義的int, long, float對應Java用int存儲,具體可以參考以上的表。
2、Socket通訊是按字節傳輸的(即8個bit位傳輸),而對於超過一個字節的類型如short 爲兩個字節,就存在兩種傳輸入方式,一種是高字節在前傳輸;一種是高字節在後傳輸。即Little-Endian和Big-Endian。
Little-Endian和Big-Endian是表示計算機字節順序的兩種格式,所謂的字節順序指的是長度跨越多個字節的數據的存放形式.
假設從地址0x00000000開始的一個字中保存有數據0x1234abcd,那麼在兩種不同的內存順序的機器上從字節的角度去看的話分別表示爲:
1)little endian:在內存中的存放順序是0x00000000-0xcd,0x00000001-0xab,0x00000002-0x34,0x00000003-0x12
2)big endian:在內存中的存放順序是0x00000000-0x12,0x00000001-0x34,0x00000002-0xab,0x00000003-0xcd
需要特別說明的是,以上假設機器是每個內存單元以8位即一個字節爲單位的.
簡單的說,ittle endian把低字節存放在內存的低位;而big endian將低字節存放在內存的高位.
現在主流的CPU,intel系列的是採用的little endian的格式存放數據,而motorola系列的CPU採用的是big endian.
網絡協議都是Big-Endian的,Java編譯的都是Big-Endian的,C編譯的程序是與機器相關的,具體是否要進行轉換是需要溝通的。假設這裏需要轉換,以下提供short轉的換成字節數組的方式:
public static byte[] ShorttoByteArray(short n) {
byte[] b = new byte[2];
b[1] = (byte) (n & 0xff);
b[0] = (byte) (n >> 8 & 0xff);
return b;
}
public static byte[] toLH(short n) {