亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

字節(jié)序(通信有用)

系統(tǒng) 1528 0
轉(zhuǎn)自(http://hi.baidu.com/cyhjason/blog/item/f599548a948282759e2fb49d.html)
有關(guān)“字節(jié)序”的描述
BIG-ENDIAN(大字節(jié)序、高字節(jié)序)
LITTLE-ENDIAN(小字節(jié)序、低字節(jié)序)
主機(jī)字節(jié)序
網(wǎng)絡(luò)字節(jié)順序
JAVA字節(jié)序

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

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

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

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

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


===============================================================================================

Big Endian and Little Endian

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

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

Big Endian

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

Little Endian

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

??? 從上面兩圖可以看出,采用big endian方式存儲(chǔ)數(shù)據(jù)是符合我們?nèi)祟惖乃季S習(xí)慣的。而little endian,!@#$%^&*,見鬼去吧 -_-|||

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

??? 無(wú)獨(dú)有偶,所有網(wǎng)絡(luò)協(xié)議也都是采用big endian的方式來(lái)傳輸數(shù)據(jù)的。所以有時(shí)我們也會(huì)把big endian方式稱之為網(wǎng)絡(luò)字節(jié)序。當(dāng)兩臺(tái)采用不同字節(jié)序的主機(jī)通信時(shí),在發(fā)送數(shù)據(jù)之前都必須經(jīng)過(guò)字節(jié)序的轉(zhuǎn)換成為網(wǎng)絡(luò)字節(jié)序后再進(jìn)行傳輸。ANSI C中提供了四個(gè)轉(zhuǎn)換字節(jié)序的宏。

========================================================================================================

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

public class FormatTransfer {
/**
? * 將int轉(zhuǎn)為低字節(jié)在前,高字節(jié)在后的byte數(shù)組
? * @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轉(zhuǎn)為高字節(jié)在前,低字節(jié)在后的byte數(shù)組
? * @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轉(zhuǎn)為低字節(jié)在前,高字節(jié)在后的byte數(shù)組
? * @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轉(zhuǎn)為高字節(jié)在前,低字節(jié)在后的byte數(shù)組
? * @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轉(zhuǎn)為高字節(jié)在前,低字節(jié)在后的byte數(shù)組

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) >> ;
??? abyte0[1] = (byte) ((0xff0000 & i) >> 16);
??? abyte0[0] = (byte) ((0xff000000 & i) >> 24);
??? return abyte0;
}


*/

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

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

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


/**
? * 將字節(jié)數(shù)組轉(zhuǎn)換為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();
}

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

/**
? * 將高字節(jié)數(shù)組轉(zhuǎn)換為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;
}

/**
? * 將低字節(jié)數(shù)組轉(zhuǎn)換為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;
}


/**
? * 高字節(jié)數(shù)組到short的轉(zhuǎn)換
? * @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;
}

/**
? * 低字節(jié)數(shù)組到short的轉(zhuǎn)換
? * @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;
}

/**
? * 高字節(jié)數(shù)組轉(zhuǎn)換為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);
}

/**
? * 低字節(jié)數(shù)組轉(zhuǎn)換為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數(shù)組中的元素倒序排列
? */
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數(shù)組
? */
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類型的值轉(zhuǎn)換為字節(jié)序顛倒過(guò)來(lái)對(duì)應(yīng)的int值
? * @param i int
? * @return int
? */
public static int reverseInt(int i) {
? int result = FormatTransfer.hBytesToInt(FormatTransfer.toLH(i));
? return result;
}

/**
? * 將short類型的值轉(zhuǎn)換為字節(jié)序顛倒過(guò)來(lái)對(duì)應(yīng)的short值
? * @param s short
? * @return short
? */
public static short reverseShort(short s) {
? short result = FormatTransfer.hBytesToShort(FormatTransfer.toLH(s));
? return result;
}

/**
? * 將float類型的值轉(zhuǎn)換為字節(jié)序顛倒過(guò)來(lái)對(duì)應(yīng)的float值
? * @param f float
? * @return float
? */
public static float reverseFloat(float f) {
? float result = FormatTransfer.hBytesToFloat(FormatTransfer.toLH(f));
? return result;
}

}

字節(jié)序(通信有用)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 精品久久久久久久久久中文字幕 | 精品国产一区二区三区久久 | 国产精品深夜福利免费观看 | 亚洲另类中文字幕 | 欧美日韩国产高清 | 天天操天天干天天爱 | 亚洲专区欧美 | 国内精品久久久久影院日本 | 久操免费在线视频 | 88国产精品欧美一区二区三区 | 精品哟啊呦v视频在线观看 精品哟哟国产在线观看 | 成人在线精品视频 | 欧美 xx性 在线 | 韩国 欧美 日产 国产精品 | 国产精品久久久久影视青草 | 国产精品人成福利视频 | 九七97影院理论片手机在线观看 | 奇米影视小说 | 国产1区2区3区在线观看 | 亚洲日韩精品欧美一区二区 | 久久福利小视频 | 日韩欧美中文字幕一区二区三区 | 久久成人午夜 | 国产精品98福利小视频 | 毛片大片免费看 | 草逼网站 | 91精品久久久久久久久网影视 | 伊人成年综合网 | 日本在线毛片视频免费看 | 亚洲欧美综合在线观看 | 手机看黄av免费网址 | 老司机午夜精品视频播放 | 亚洲欧美色综合大色 | a级毛片免费完整视频 | 一级特黄女人生活片 | 五月婷中文字幕 | 亚洲久草在线 | 91福利影院 | 一级一毛片 | 国产一区在线播放 | 久久免费视频在线观看 |