• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            A Za, A Za, Fighting...

            堅(jiān)信:勤能補(bǔ)拙

            2011知識(shí)點(diǎn) - 大端模式與小端模式、網(wǎng)絡(luò)字節(jié)順序與主機(jī)字節(jié)順序 (經(jīng)典)[zz]

            大端模式與小端模式
            一、概念及詳解
              在各種體系的計(jì)算機(jī)中通常采用的字節(jié)存儲(chǔ)機(jī)制主要有兩種: big-endian和little-endian,即大端模式和小端模式。
              先回顧兩個(gè)關(guān)鍵詞,MSB和LSB:
              MSB:Most Significant Bit ------- 最高有效位
                    LSB:Least Significant Bit ------- 最低有效位
              大端模式(big-edian)
              big-endian:MSB存放在最低端的地址上。
              舉例,雙字節(jié)數(shù)0x1234以big-endian的方式存在起始地址0x00002000中:
                    | data |<-- address
                    | 0x12 |<-- 0x00002000
                    | 0x34 |<-- 0x00002001
              在Big-Endian中,對(duì)于bit序列中的序號(hào)編排方式如下(以雙字節(jié)數(shù)0x8B8A為例):
                    bit | 0 1 2 3 4 5 6 7 | 8 9 10 11 12 13 14 15
                    ------MSB----------------------------------LSB
                    val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 |
                    +--------------------------------------------+
                    = 0x8 B 8 A
              小端模式(little-endian)
              little-endian:LSB存放在最低端的地址上。
              舉例,雙字節(jié)數(shù)0x1234以little-endian的方式存在起始地址0x00002000中:
            | data |<-- address
                    | 0x34 |<-- 0x00002000
                    | 0x12 |<-- 0x00002001
              在Little-Endian中,對(duì)于bit序列中的序號(hào)編排和Big-Endian剛好相反,其方式如下(以雙字節(jié)數(shù)0x8B8A為例):
            bit | 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0
                    ------MSB-----------------------------------LSB
                    val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 |
                    +---------------------------------------------+
                    = 0x8 B 8 A 
            二、數(shù)組在大端小端情況下的存儲(chǔ):
              以u(píng)nsigned int value = 0x12345678為例,分別看看在兩種字節(jié)序下其存儲(chǔ)情況,我們可以用unsigned char buf[4]來表示value:
              Big-Endian: 低地址存放高位,如下:
                   高地址
                    ---------------
                    buf[3] (0x78) -- 低位
                    buf[2] (0x56)
                    buf[1] (0x34)
                    buf[0] (0x12) -- 高位
                    ---------------
                    低地址
            Little-Endian: 低地址存放低位,如下:
                    高地址
                    ---------------
                    buf[3] (0x12) -- 高位
                    buf[2] (0x34)
                    buf[1] (0x56)
                    buf[0] (0x78) -- 低位
                    --------------
                    低地址

              三、大端小端轉(zhuǎn)換方法:
              Big-Endian轉(zhuǎn)換成Little-Endian如下:
            #define BigtoLittle16(A)                 ((((uint16)(A) & 0xff00) >> 8) | \
                                                                      (((uint16)(A) & 0x00ff) << 8))
            #define BigtoLittle32(A)                 ((((uint32)(A) & 0xff000000) >> 24) | \
                                                                      (((uint32)(A) & 0x00ff0000) >> 8) | \
                                                                      (((uint32)(A) & 0x0000ff00) << 8) | \
                                                                      (((uint32)(A) & 0x000000ff) << 24))

              四、大端小端檢測(cè)方法:
              如何檢查處理器是big-endian還是little-endian?
              聯(lián)合體union的存放順序是所有成員都從低地址開始存放,利用該特性就可以輕松地獲得了CPU對(duì)內(nèi)存采用Little-endian還是Big-endian模式讀寫。
            int checkCPUendian()
            {
            union
            {
            unsigned int a;
            unsigned char b;
            }c;
            c.a = 1;
            return (c.b == 1);
            }
            /*return 1 : little-endian, return 0:big-endian*/ 

            網(wǎng)絡(luò)字節(jié)順序

            1、字節(jié)內(nèi)的比特位不受這種順序的影響
            比如一個(gè)字節(jié) 1000 0000 (或表示為十六進(jìn)制 80H)不管是什么順序其內(nèi)存中的表示法都是這樣。
            2、大于1個(gè)字節(jié)的數(shù)據(jù)類型才有字節(jié)順序問題
            比如 Byte A,這個(gè)變量只有一個(gè)字節(jié)的長度,所以根據(jù)上一條沒有字節(jié)順序問題。所以字節(jié)順序是“字節(jié)之間的相對(duì)順序”的意思。
            3、大于1個(gè)字節(jié)的數(shù)據(jù)類型的字節(jié)順序有兩種
            比如 short B,這是一個(gè)兩字節(jié)的數(shù)據(jù)類型,這時(shí)就有字節(jié)之間的相對(duì)順序問題了。
            網(wǎng)絡(luò)字節(jié)順序是“所見即所得”的順序。而Intel類型的CPU的字節(jié)順序與此相反。
            比如上面的 short B=0102H(十六進(jìn)制,每兩位表示一個(gè)字節(jié)的寬度)。所見到的是“0102”,按一般數(shù)學(xué)常識(shí),數(shù)軸從左到右的方向增加,即內(nèi)存地址從左到右增加的話,在內(nèi)存中這個(gè) short B的字節(jié)順序是:
            01 02
            這就是網(wǎng)絡(luò)字節(jié)順序。所見到的順序和在內(nèi)存中的順序是一致的!
            而相反的字節(jié)順序就不同了,其在內(nèi)存中的順序?yàn)椋?2 01
            假設(shè)通過抓包得到網(wǎng)絡(luò)數(shù)據(jù)的兩個(gè)字節(jié)流為:01 02
            如果這表示兩個(gè) Byte類型的變量,那么自然不需要考慮字節(jié)順序的問題。
            如果這表示一個(gè) short 變量,那么就需要考慮字節(jié)順序問題。根據(jù)網(wǎng)絡(luò)字節(jié)順序“所見即所得”的規(guī)則,這個(gè)變量的值就是:0102
            假設(shè)本地主機(jī)是Intel類型的,那么要表示這個(gè)變量,有點(diǎn)麻煩:
            定義變量 short X,
            字節(jié)流地址為:pt,按順序讀取內(nèi)存是為
            x=*((short*)pt);
            那么X的內(nèi)存順序當(dāng)然是 01 02
            按非“所見即所得”的規(guī)則,這個(gè)內(nèi)存順序和看到的一樣顯然是不對(duì)的,所以要把這兩個(gè)字節(jié)的位置調(diào)換。
            調(diào)換的方法可以自己定義,但用已經(jīng)有的API還是更為方便。

            網(wǎng)絡(luò)字節(jié)順序與主機(jī)字節(jié)順序
            NBO與HBO 網(wǎng)絡(luò)字節(jié)順序NBO(Network Byte Order):按從高到低的順序存儲(chǔ),在網(wǎng)絡(luò)上使用統(tǒng)一的網(wǎng)絡(luò)字節(jié)順序,可以避免兼容性問題。主機(jī)字節(jié)順序(HBO,Host Byte Order):不同的機(jī)器HBO不相同,與CPU設(shè)計(jì)有關(guān)計(jì)算機(jī)數(shù)據(jù)存儲(chǔ)有兩種字節(jié)優(yōu)先順序:高位字節(jié)優(yōu)先和低位字節(jié)優(yōu)先。Internet上數(shù)據(jù)以高位字節(jié)優(yōu)先順序在網(wǎng)絡(luò)上傳輸,所以對(duì)于在內(nèi)部是以低位字節(jié)優(yōu)先方式存儲(chǔ)數(shù)據(jù)的機(jī)器,在Internet上傳輸數(shù)據(jù)時(shí)就需要進(jìn)行轉(zhuǎn)換。 

            htonl()
            簡述:
                將主機(jī)的無符號(hào)長整形數(shù)轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)順序。
                #include <winsock.h>
                u_long PASCAL FAR htonl( u_long hostlong);
                hostlong:主機(jī)字節(jié)順序表達(dá)的32位數(shù)。
            注釋:
                本函數(shù)將一個(gè)32位數(shù)從主機(jī)字節(jié)順序轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)順序。
            返回值:
                htonl()返回一個(gè)網(wǎng)絡(luò)字節(jié)順序的值。

            inet_ntoa()
            簡述:
            將網(wǎng)絡(luò)地址轉(zhuǎn)換成“.”點(diǎn)隔的字符串格式。
            #include <winsock.h>
            char FAR* PASCAL FAR inet_ntoa( struct in_addr in);
            in:一個(gè)表示Internet主機(jī)地址的結(jié)構(gòu)。
            注釋:
            本函數(shù)將一個(gè)用in參數(shù)所表示的Internet地址結(jié)構(gòu)轉(zhuǎn)換成以“.” 間隔的諸如“a.b.c.d”的字符串形式。請(qǐng)注意inet_ntoa()返回的字符串存放在WINDOWS套接口實(shí)現(xiàn)所分配的內(nèi)存中。應(yīng)用程序不應(yīng)假設(shè)該內(nèi)存是如何分配的。在同一個(gè)線程的下一個(gè)WINDOWS套接口調(diào)用前,數(shù)據(jù)將保證是有效。
            返回值:
            若無錯(cuò)誤發(fā)生,inet_ntoa()返回一個(gè)字符指針。否則的話,返回NULL。其中的數(shù)據(jù)應(yīng)在下一個(gè)WINDOWS套接口調(diào)用前復(fù)制出來。

            網(wǎng)絡(luò)中傳輸?shù)臄?shù)據(jù)有的和本地字節(jié)存儲(chǔ)順序一致,而有的則截然不同,為了數(shù)據(jù)的一致性,就要把本地的數(shù)據(jù)轉(zhuǎn)換成網(wǎng)絡(luò)上使用的格式,然后發(fā)送出去,接收的時(shí)候也是一樣的,經(jīng)過轉(zhuǎn)換然后才去使用這些數(shù)據(jù),基本的庫函數(shù)中提供了這樣的可以進(jìn)行字節(jié)轉(zhuǎn)換的函數(shù),如和htons( ) htonl( ) ntohs( ) ntohl( ),這里n表示network,h表示host,htons( ) htonl( )用于本地字節(jié)向網(wǎng)絡(luò)字節(jié)轉(zhuǎn)換的場(chǎng)合,s表示short,即對(duì)2字節(jié)操作,l表示long即對(duì)4字節(jié)操作。同樣ntohs( )ntohl( )用于網(wǎng)絡(luò)字節(jié)向本地格式轉(zhuǎn)換的場(chǎng)合。

            posted on 2011-09-21 13:03 simplyzhao 閱讀(233) 評(píng)論(0)  編輯 收藏 引用 所屬分類: R_找工復(fù)習(xí)2011

            導(dǎo)航

            <2010年9月>
            2930311234
            567891011
            12131415161718
            19202122232425
            262728293012
            3456789

            統(tǒng)計(jì)

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            99久久精品国产一区二区| 久久久久97国产精华液好用吗| 久久精品国产亚洲5555| 国产精品久久久久久搜索| 久久夜色精品国产网站| 久久精品国产亚洲AV久| 国产aⅴ激情无码久久| 国产精品久久久久久久久软件| 欧美久久久久久午夜精品| 久久久久九国产精品| 开心久久婷婷综合中文字幕| 久久精品三级视频| 国产精品成人久久久| 伊人久久亚洲综合影院| 国内精品伊人久久久久777| 精品一二三区久久aaa片| 午夜精品久久久久久久久| 成人国内精品久久久久影院| 996久久国产精品线观看| 91精品日韩人妻无码久久不卡| 久久国产香蕉一区精品| 国产精品久久久久a影院| 久久精品中文字幕无码绿巨人| 国产亚洲美女精品久久久久狼| 久久国产综合精品五月天| 久久精品无码一区二区WWW| 国产午夜精品理论片久久影视| 久久精品亚洲欧美日韩久久| 综合久久精品色| 国产精品欧美久久久天天影视| 国产三级观看久久| 亚洲精品无码久久久久久| 97精品伊人久久久大香线蕉| 免费精品国产日韩热久久| jizzjizz国产精品久久| 国产精品日韩深夜福利久久| 久久久久一本毛久久久| 亚洲国产精品无码久久| 99久久www免费人成精品| 一本色道久久综合狠狠躁| 国产精品久久久99|