C++/java之間的Socket通信大小端注意事項


      在一個物聯往項目中,需要java雲平台與一個客戶端做socket定制協議的通信;然而在第一次測試時,並沒有按照預想的那樣完成解析。查找資料以后是因為客戶端的數據讀取方式為小端模式,而java默認采用大端模式。

    在計算機系統中,我們是以字節為單位的,每個地址單元都對應着一個字節,一個字節為 8bit。但是在C語言中除了8bit的char之外,還有16bit的short型,32bit的long型(要看具體的編譯器),另外,對於位數大於 8位的處理器,例如16位或者32位的處理器,由於寄存器寬度大於一個字節,那么必然存在着一個如何將多個字節安排的問題。因此就導致了大端存儲模式和小端存儲模式。

     目前Intel的80x86系列芯片是唯一還在堅持使用小端的芯片,而MIPS和ARM等芯片要么采用全部大端的方式儲存,要么提供選項支持大端——可以在大小端之間切換。另外,對於大小端的處理也和編譯器的實現有關,在C語言中,默認是小端(但在一些對於單片機的實現中卻是基於大端,比如Keil 51C),Java是平台無關的,默認是大端。在網絡上傳輸數據普遍采用的都是大端。

     如果遇到了大端與小端之間的通信。應該遵照大小端的數據讀取原理,做相應的轉換。(以java的大端模式為例)

    現在以java的32位的int型數據為例子,做轉換示例;

    如下:是大端int轉化為小端的byte數組:將int型的4個高位16進制數逆序放入字節數組中;

 public static byte[] intToMinByteArray(int i) {
        byte[] result = new byte[4];
        //由高位到低位
        result[3] = (byte) ((i >> 24) & 0xFF);
        result[2] = (byte) ((i >> 16) & 0xFF);
        result[1] = (byte) ((i >> 8) & 0xFF);
        result[0] = (byte) (i & 0xFF);
        return result;
    }

 

   如下是小端數組轉化為大端int數的示例:采用字符串表示的16進制數來轉換為Integer的api。

public static int byteLittleEndianToInt(byte[] bytes) {
        String nubHexStr = "";
        byte[] temp = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            System.out.println("值:" + bytes[bytes.length - i - 1]);
            System.out.println("對應的16進制值:"+Integer.toHexString(bytes[bytes.length - i - 1]));
            nubHexStr += Integer.toHexString(bytes[bytes.length - i - 1]);
        }
        System.out.println("16進制:" + nubHexStr);
        return Integer.parseInt(nubHexStr, 16);
    }

以上代碼來自Felix。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM