• <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...

            堅信:勤能補拙

            2011知識點 - 大端模式與小端模式、網絡字節順序與主機字節順序 (經典)[zz]

            大端模式與小端模式
            一、概念及詳解
              在各種體系的計算機中通常采用的字節存儲機制主要有兩種: big-endian和little-endian,即大端模式和小端模式。
              先回顧兩個關鍵詞,MSB和LSB:
              MSB:Most Significant Bit ------- 最高有效位
                    LSB:Least Significant Bit ------- 最低有效位
              大端模式(big-edian)
              big-endian:MSB存放在最低端的地址上。
              舉例,雙字節數0x1234以big-endian的方式存在起始地址0x00002000中:
                    | data |<-- address
                    | 0x12 |<-- 0x00002000
                    | 0x34 |<-- 0x00002001
              在Big-Endian中,對于bit序列中的序號編排方式如下(以雙字節數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存放在最低端的地址上。
              舉例,雙字節數0x1234以little-endian的方式存在起始地址0x00002000中:
            | data |<-- address
                    | 0x34 |<-- 0x00002000
                    | 0x12 |<-- 0x00002001
              在Little-Endian中,對于bit序列中的序號編排和Big-Endian剛好相反,其方式如下(以雙字節數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 
            二、數組在大端小端情況下的存儲:
              以unsigned int value = 0x12345678為例,分別看看在兩種字節序下其存儲情況,我們可以用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) -- 低位
                    --------------
                    低地址

              三、大端小端轉換方法:
              Big-Endian轉換成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))

              四、大端小端檢測方法:
              如何檢查處理器是big-endian還是little-endian?
              聯合體union的存放順序是所有成員都從低地址開始存放,利用該特性就可以輕松地獲得了CPU對內存采用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*/ 

            網絡字節順序

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

            網絡字節順序與主機字節順序
            NBO與HBO 網絡字節順序NBO(Network Byte Order):按從高到低的順序存儲,在網絡上使用統一的網絡字節順序,可以避免兼容性問題。主機字節順序(HBO,Host Byte Order):不同的機器HBO不相同,與CPU設計有關計算機數據存儲有兩種字節優先順序:高位字節優先和低位字節優先。Internet上數據以高位字節優先順序在網絡上傳輸,所以對于在內部是以低位字節優先方式存儲數據的機器,在Internet上傳輸數據時就需要進行轉換。 

            htonl()
            簡述:
                將主機的無符號長整形數轉換成網絡字節順序。
                #include <winsock.h>
                u_long PASCAL FAR htonl( u_long hostlong);
                hostlong:主機字節順序表達的32位數。
            注釋:
                本函數將一個32位數從主機字節順序轉換成網絡字節順序。
            返回值:
                htonl()返回一個網絡字節順序的值。

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

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

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

            導航

            <2011年9月>
            28293031123
            45678910
            11121314151617
            18192021222324
            2526272829301
            2345678

            統計

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            国产午夜精品久久久久九九| 久久婷婷色综合一区二区| 久久久久久久精品成人热色戒| 色综合久久久久| 久久99精品免费一区二区| 久久久久国产一区二区| 久久91精品久久91综合| 国产精品免费久久久久影院| 99精品久久精品| 国产成人精品久久综合| 欧美亚洲国产精品久久久久| 久久国语露脸国产精品电影| 久久99国产精品久久99小说 | 性欧美大战久久久久久久| 99久久香蕉国产线看观香| 久久99精品国产99久久| 亚洲国产成人久久精品99| 久久ZYZ资源站无码中文动漫| 久久成人精品视频| 久久久久久亚洲AV无码专区| 久久久精品波多野结衣| 久久国产精品无码HDAV| 久久这里只有精品首页| 欧美与黑人午夜性猛交久久久| 97久久婷婷五月综合色d啪蜜芽| 一本大道久久a久久精品综合| 久久妇女高潮几次MBA| 久久综合九色欧美综合狠狠| 99久久精品国产毛片| 国产韩国精品一区二区三区久久| 亚洲欧洲精品成人久久奇米网| 欧美国产成人久久精品| 久久亚洲中文字幕精品一区| 四虎国产精品免费久久| 亚洲精品国产成人99久久| 日日躁夜夜躁狠狠久久AV| 亚洲а∨天堂久久精品9966| 91精品日韩人妻无码久久不卡| 久久精品欧美日韩精品| 亚洲精品WWW久久久久久| 夜夜亚洲天天久久|