欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Big Endian and Little Endian(字節序)

1.BIG-ENDIAN、LITTLE-ENDIAN跟多字節類(lèi)型的數據有關(guān)的比如int,short,long型,而對單字節數據byte卻沒(méi)有影響。BIG-ENDIAN就是低位字節排放在內存的低端,高位字節排放在內存的高端。而LITTLE-ENDIAN正好相反。
比如 int a = 0x05060708
在BIG-ENDIAN的情況下存放為:
字節號 0 1 2 3
數據 05 06 07 08
在LITTLE-ENDIAN的情況下存放為:
字節號 0 1 2 3
數據 08 07 06 05

2.BIG-ENDIAN、LITTLE-ENDIAN、跟CPU有關(guān)的,每一種CPU不是BIG-ENDIAN就是LITTLE-ENDIAN、。IA架構的CPU中是Little-Endian,而PowerPC 、SPARC和Motorola處理器。這其實(shí)就是所謂的主機字節序。而網(wǎng)絡(luò )字節序是指數據在網(wǎng)絡(luò )上傳輸時(shí)是大頭還是小頭的,在Internet的網(wǎng)絡(luò )字節序是BIG-ENDIAN。所謂的JAVA字節序指的是在JAVA虛擬機中多字節類(lèi)型數據的存放順序,JAVA字節序也是BIG-ENDIAN。

3.所以在用C/C++寫(xiě)通信程序時(shí),在發(fā)送數據前務(wù)必用htonlhtons去把整型和短整型的數據進(jìn)行從主機字節序到網(wǎng)絡(luò )字節序的轉換,而接收數據后對于整型和短整型數據則必須調用ntohlntohs實(shí)現從網(wǎng)絡(luò )字節序到主機字節序的轉換。如果通信的一方是JAVA程序、一方是C/C++程序時(shí),則需要在C/C++一側使用以上幾個(gè)方法進(jìn)行字節序的轉換,而JAVA一側,則不需要做任何處理,因為JAVA字節序與網(wǎng)絡(luò )字節序都是BIG-ENDIAN,只要C/C++一側能正確進(jìn)行轉換即可(發(fā)送前從主機序到網(wǎng)絡(luò )序,接收時(shí)反變換)。如果通信的雙方都是JAVA,則根本不用考慮字節序的問(wèn)題了。

4.如果網(wǎng)絡(luò )上全部是PowerPC,SPARC和Motorola CPU的主機那么不會(huì )出現任何問(wèn)題,但由于實(shí)際存在大量的IA架構的CPU,所以經(jīng)常出現數據傳輸錯誤。

5.文章開(kāi)頭所提出的問(wèn)題,就是因為程序運行在X86架構的PC SERVER上,發(fā)送數據的一端用C實(shí)現的,接收一端是用JAVA實(shí)現的,而發(fā)送端在發(fā)送數據前未進(jìn)行從主機字節序到網(wǎng)絡(luò )字節序的轉換,這樣接收端接收到的是LITTLE-ENDIAN的數據,數據解釋自然出錯。
具體數據如下,實(shí)際發(fā)送的數據為23578
發(fā)送端發(fā)送數據: 1A 5C
接收端接收到數據后,按BIG-ENDIAN進(jìn)行解釋具體數據是多少?你們自己去計算并比較吧!


Big Endian and Little Endian


    談到字節序的問(wèn)題,必然牽涉到兩大CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用big endian方式存儲數據,而x86系列則采用little endian方式存儲數據。那么究竟什么是big endian,什么又是little endian呢?

    其實(shí)big endian是指低地址存放最高有效字節(MSB),而little endian則是低地址存放最低有效字節(LSB),即常說(shuō)的低位在先,高位在后。
    用文字說(shuō)明可能比較抽象,下面用圖像加以說(shuō)明。比如數字0x12345678在兩種不同字節序CPU中的存儲順序如下所示:

Big Endian

  低地址                                     高地址
  ----------------------------------------------->
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |     12     |      34    |     56      |     78    |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Little Endian

  低地址                                     高地址
  ----------------------------------------------->
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |     78     |      56    |     34      |     12    |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    從上面兩圖可以看出,采用big endian方式存儲數據是符合我們人類(lèi)的思維習慣的。而little endian,!@#$%^&*,見(jiàn)鬼去吧 -_-|||

    為什么要注意字節序的問(wèn)題呢?你可能這么問(wèn)。當然,如果你寫(xiě)的程序只在單機環(huán)境下面運行,并且不和別人的程序打交道,那么你完全可以忽略字節序的存在。但是,如果你的程序要跟別人的程序產(chǎn)生交互呢?尤其是當你把你在微機上運算的結果運用到計算機群上去的話(huà)。在這里我想說(shuō)說(shuō)兩種語(yǔ)言。C/C++語(yǔ)言編寫(xiě)的程序里數據存儲順序是跟編譯平臺所在的CPU相關(guān)的,而JAVA編寫(xiě)的程序則唯一采用big endian方式來(lái)存儲數據。試想,如果你用C/C++語(yǔ)言在x86平臺下編寫(xiě)的程序跟別人的JAVA程序互通時(shí)會(huì )產(chǎn)生什么結果?就拿上面的 0x12345678來(lái)說(shuō),你的程序傳遞給別人的一個(gè)數據,將指向0x12345678的指針傳給了JAVA程序,由于JAVA采取big endian方式存儲數據,很自然的它會(huì )將你的數據翻譯為0x78563412。什么?竟然變成另外一個(gè)數字了?是的,就是這種后果。因此,在你的C程序傳給JAVA程序之前有必要進(jìn)行字節序的轉換工作。

    無(wú)獨有偶,所有網(wǎng)絡(luò )協(xié)議也都是采用big endian的方式來(lái)傳輸數據的。所以有時(shí)我們也會(huì )把big endian方式稱(chēng)之為網(wǎng)絡(luò )字節序。當兩臺采用不同字節序的主機通信時(shí),在發(fā)送數據之前都必須經(jīng)過(guò)字節序的轉換成為網(wǎng)絡(luò )字節序后再進(jìn)行傳輸。ANSI C中提供了四個(gè)轉換字節序的宏。
 
   ( 以下補充轉自http://zhidao.baidu.com/question/10925603.html )
 
    可是有朋友仍然會(huì )問(wèn),CPU存儲一個(gè)字節的數據時(shí)其字節內的8個(gè)比特之間的順序是否也有big endian和little endian之分?或者說(shuō)是否有比特序的不同?

    實(shí)際上,這個(gè)比特序是同樣存在的。下面以數字0xB4(10110100)用圖加以說(shuō)明。

Big Endian

msb lsb
------------------------------>
+-+-+-+-+-+-+-+-+-+-+-+-
| 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 |
+-+-+-+-+-+-+-+-+-+-+-+-

Little Endian

lsb msb
------------------------------>
+-+-+-+-+-+-+-+-+-+-+-+-
| 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 |
+-+-+-+-+-+-+-+-+-+-+-+-


     實(shí)際上,由于CPU存儲數據操作的最小單位是一個(gè)字節,其內部的比特序是什么樣對我們的程序來(lái)說(shuō)是一個(gè)黑盒子。也就是說(shuō),你給我一個(gè)指向0xB4這個(gè)數的指針,對于big endian方式的CPU來(lái)說(shuō),它是從左往右依次讀取這個(gè)數的8個(gè)比特;而對于little endian方式的CPU來(lái)說(shuō),則正好相反,是從右往左依次讀取這個(gè)數的8個(gè)比特。而我們的程序通過(guò)這個(gè)指針訪(fǎng)問(wèn)后得到的數就是0xB4,字節內部的比特序對于程序來(lái)說(shuō)是不可見(jiàn)的,其實(shí)這點(diǎn)對于單機上的字節序來(lái)說(shuō)也是一樣的。

     那可能有人又會(huì )問(wèn),如果是網(wǎng)絡(luò )傳輸呢?會(huì )不會(huì )出問(wèn)題?是不是也要通過(guò)什么函數轉換一下比特序?嗯,這個(gè)問(wèn)題提得很好。假設little endian方式的CPU要傳給big endian方式CPU一個(gè)字節的話(huà),其本身在傳輸之前會(huì )在本地就讀出這個(gè)8比特的數,然后再按照網(wǎng)絡(luò )字節序的順序來(lái)傳輸這8個(gè)比特,這樣的話(huà)到了接收端不會(huì )出現任何問(wèn)題。而假如要傳輸一個(gè)32比特的數的話(huà),由于這個(gè)數在littel endian方存儲時(shí)占了4個(gè)字節,而網(wǎng)絡(luò )傳輸是以字節為單位進(jìn)行的,little endian方的CPU讀出第一個(gè)字節后發(fā)送,實(shí)際上這個(gè)字節是原數的LSB,到了接收方反倒成了MSB從而發(fā)生混亂。



/**
* 通信格式轉換
*
* Java和一些windows編程語(yǔ)言如c、c++、delphi所寫(xiě)的網(wǎng)絡(luò )程序進(jìn)行通訊時(shí),需要進(jìn)行相應的轉換
* 高、低字節之間的轉換
* windows的字節序為低字節開(kāi)頭
* linux,unix的字節序為高字節開(kāi)頭
* java則無(wú)論平臺變化,都是高字節開(kāi)頭
*/

public class FormatTransfer {
/**
  * 將int轉為低字節在前,高字節在后的byte數組
  * @param n int
  * @return byte[]
  */
public static byte[] toLH(int n) {
  byte[] b = new byte[4];
  b[0] = (byte) (n & 0xff);
  b[1] = (byte) (n >> 8 & 0xff);
  b[2] = (byte) (n >> 16 & 0xff);
  b[3] = (byte) (n >> 24 & 0xff);
  return b;
}

/**
  * 將int轉為高字節在前,低字節在后的byte數組
  * @param n int
  * @return byte[]
  */
public static byte[] toHH(int n) {
  byte[] b = new byte[4];
  b[3] = (byte) (n & 0xff);
  b[2] = (byte) (n >> 8 & 0xff);
  b[1] = (byte) (n >> 16 & 0xff);
  b[0] = (byte) (n >> 24 & 0xff);
  return b;
}

/**
  * 將short轉為低字節在前,高字節在后的byte數組
  * @param n short
  * @return byte[]
  */
public static byte[] toLH(short n) {
  byte[] b = new byte[2];
  b[0] = (byte) (n & 0xff);
  b[1] = (byte) (n >> 8 & 0xff);
  return b;
}

/**
  * 將short轉為高字節在前,低字節在后的byte數組
  * @param n short
  * @return byte[]
  */
public static byte[] toHH(short n) {
  byte[] b = new byte[2];
  b[1] = (byte) (n & 0xff);
  b[0] = (byte) (n >> 8 & 0xff);
  return b;
}

 

/**
  * 將將int轉為高字節在前,低字節在后的byte數組

public static byte[] toHH(int number) {
  int temp = number;
  byte[] b = new byte[4];
  for (int i = b.length - 1; i > -1; i--) {
    b = new Integer(temp & 0xff).byteValue();
    temp = temp >> 8;
  }
  return b;
}

public static byte[] IntToByteArray(int i) {
    byte[] abyte0 = new byte[4];
    abyte0[3] = (byte) (0xff & i);
    abyte0[2] = (byte) ((0xff00 & i) >> 8);
    abyte0[1] = (byte) ((0xff0000 & i) >> 16);
    abyte0[0] = (byte) ((0xff000000 & i) >> 24);
    return abyte0;
}


*/

/**
  * 將float轉為低字節在前,高字節在后的byte數組
  */
public static byte[] toLH(float f) {
  return toLH(Float.floatToRawIntBits(f));
}

/**
  * 將float轉為高字節在前,低字節在后的byte數組
  */
public static byte[] toHH(float f) {
  return toHH(Float.floatToRawIntBits(f));
}

/**
  * 將String轉為byte數組
  */
public static byte[] stringToBytes(String s, int length) {
  while (s.getBytes().length < length) {
    s += " ";
  }
  return s.getBytes();
}


/**
  * 將字節數組轉換為String
  * @param b byte[]
  * @return String
  */
public static String bytesToString(byte[] b) {
  StringBuffer result = new StringBuffer("");
  int length = b.length;
  for (int i=0; i<length; i++) {
    result.append((char)(b & 0xff));
  }
  return result.toString();
}

/**
  * 將字符串轉換為byte數組
  * @param s String
  * @return byte[]
  */
public static byte[] stringToBytes(String s) {
  return s.getBytes();
}

/**
  * 將高字節數組轉換為int
  * @param b byte[]
  * @return int
  */
public static int hBytesToInt(byte[] b) {
  int s = 0;
  for (int i = 0; i < 3; i++) {
    if (b >= 0) {
    s = s + b;
    } else {
    s = s + 256 + b;
    }
    s = s * 256;
  }
  if (b[3] >= 0) {
    s = s + b[3];
  } else {
    s = s + 256 + b[3];
  }
  return s;
}

/**
  * 將低字節數組轉換為int
  * @param b byte[]
  * @return int
  */
public static int lBytesToInt(byte[] b) {
  int s = 0;
  for (int i = 0; i < 3; i++) {
    if (b[3-i] >= 0) {
    s = s + b[3-i];
    } else {
    s = s + 256 + b[3-i];
    }
    s = s * 256;
  }
  if (b[0] >= 0) {
    s = s + b[0];
  } else {
    s = s + 256 + b[0];
  }
  return s;
}


/**
  * 高字節數組到short的轉換
  * @param b byte[]
  * @return short
  */
public static short hBytesToShort(byte[] b) {
  int s = 0;
  if (b[0] >= 0) {
    s = s + b[0];
    } else {
    s = s + 256 + b[0];
    }
    s = s * 256;
  if (b[1] >= 0) {
    s = s + b[1];
  } else {
    s = s + 256 + b[1];
  }
  short result = (short)s;
  return result;
}

/**
  * 低字節數組到short的轉換
  * @param b byte[]
  * @return short
  */
public static short lBytesToShort(byte[] b) {
  int s = 0;
  if (b[1] >= 0) {
    s = s + b[1];
    } else {
    s = s + 256 + b[1];
    }
    s = s * 256;
  if (b[0] >= 0) {
    s = s + b[0];
  } else {
    s = s + 256 + b[0];
  }
  short result = (short)s;
  return result;
}

/**
  * 高字節數組轉換為float
  * @param b byte[]
  * @return float
  */
public static float hBytesToFloat(byte[] b) {
  int i = 0;
  Float F = new Float(0.0);
  i = ((((b[0]&0xff)<<8 | (b[1]&0xff))<<8) | (b[2]&0xff))<<8 | (b[3]&0xff);
  return F.intBitsToFloat(i);
}

/**
  * 低字節數組轉換為float
  * @param b byte[]
  * @return float
  */
public static float lBytesToFloat(byte[] b) {
  int i = 0;
  Float F = new Float(0.0);
  i = ((((b[3]&0xff)<<8 | (b[2]&0xff))<<8) | (b[1]&0xff))<<8 | (b[0]&0xff);
  return F.intBitsToFloat(i);
}

/**
  * 將byte數組中的元素倒序排列
  */
public static byte[] bytesReverseOrder(byte[] b) {
  int length = b.length;
  byte[] result = new byte[length];
  for(int i=0; i<length; i++) {
    result[length-i-1] = b;
  }
  return result;
}

/**
  * 打印byte數組
  */
public static void printBytes(byte[] bb) {
  int length = bb.length;
  for (int i=0; i<length; i++) {
    System.out.print(bb + " ");
  }
  System.out.println("");
}

public static void logBytes(byte[] bb) {
  int length = bb.length;
  String ut = "";
  for (int i=0; i<length; i++) {
    ut = out + bb + " ";
  }

}

/**
  * 將int類(lèi)型的值轉換為字節序顛倒過(guò)來(lái)對應的int值
  * @param i int
  * @return int
  */
public static int reverseInt(int i) {
  int result = FormatTransfer.hBytesToInt(FormatTransfer.toLH(i));
  return result;
}

/**
  * 將short類(lèi)型的值轉換為字節序顛倒過(guò)來(lái)對應的short值
  * @param s short
  * @return short
  */
public static short reverseShort(short s) {
  short result = FormatTransfer.hBytesToShort(FormatTransfer.toLH(s));
  return result;
}

/**
  * 將float類(lèi)型的值轉換為字節序顛倒過(guò)來(lái)對應的float值
  * @param f float
  * @return float
  */
public static float reverseFloat(float f) {
  float result = FormatTransfer.hBytesToFloat(FormatTransfer.toLH(f));
  return result;
}

}

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Socket網(wǎng)絡(luò )通訊開(kāi)發(fā)總結之:Java 與 C進(jìn)行Socket通訊
Java中byte數組與long數組相互轉化
淺談字節序(Byte Order)及其相關(guān)操作
[C#]大小端字節序(Big Endian和Little Endian)
【Java】SubarrayUtils(查找子數組工具類(lèi))
java與c/c 進(jìn)行socket通信的一些問(wèn)題(2)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久