Socket:java與C之間的文件傳送(JAVA與C通信需要注意的地方)

http://blog.csdn.net/mhapdream/article/details/8929253  Socket:java與C之間的文件傳送<1>(C語言之間的通信)
http://blog.csdn.net/mhapdream/article/details/8929457  Socket:java與C之間的文件傳送<2>(JAVA語言之間的通信)
http://blog.csdn.net/mhapdream/article/details/8929590  Socket:java與C之間的文件傳送<3>(JAVA與C通信需要注意的地方)
http://blog.csdn.net/mhapdream/article/details/8929638  Socket:java與C之間的文件傳送<4>(JAVA與C通信)

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) {
    byte[] b = new byte[2];
    b[0] = (byte) (n & 0xff);
    b[1] = (byte) (n >> 8 & 0xff);
    return b;
  }
其它的類型轉換類似,無非是根據類型在判斷用幾個字節進行存儲而已。

3、由於Socket通訊是按字節進行傳輸的,而在Java中只有byte是一個字節,故可以將其它類型都轉換成byte數組來存儲,如:short用兩位的字節數組存儲,需轉換了換以上方法進行,而int用四位的字節數組來存儲,對String類型,直接用String.getBytes()來得到它的字節數組。

4、Java的byte與C語言的unsign char雖然都是一個字節存儲,但具體的表示內容是不同的,C的無符號char是取值的範圍0--255,而Java中byte取值的範圍是-128—127,故在實現C語言的字符串時(C是用char[]來表示字符串的),Java這邊需要進行轉換來模仿C語的unsign char,具體實現函數如下:
  // 將有符號的char轉換成無符號的char
  public static char[] ToUnsignedChar(char[] signChar) {
    for (int i = 0; i < signChar.length; i++) {
      int x = ((byte) signChar[i]) >= 0 ? signChar[i] : ((byte) signChar[i]) + 256;
      signChar[i] = (char) x;
    }
    return signChar;
  }
這裏的關鍵點是當signChar[i] < 0時,即加上256,將其轉換到0--255中來。

通過以上四個方面的注意,基本上就可以實現Java與C進行Socket通訊了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章