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

            yehao's Blog

            關于網絡字節序

            不同的 CPU 有不同的字節序類型 這些字節序是指整數在內存中保存的順序 這個叫做主機序 
            最常見的有兩種 

            1 
             Little endian :將低序字節存儲在起始地址 
            2 
             Big endian :將高序字節存儲在起始地址 

            LE little-endian 
            最符合人的思維的字節序 
            地址低位存儲值的低位 

            地址高位存儲值的高位 

            怎么講是最符合人的思維的字節序,是因為從人的第一觀感來說 

            低位值小,就應該放在內存地址小的地方,也即內存地址低位 

            反之,高位值就應該放在內存地址大的地方,也即內存地址高位 


            BE big-endian 
            最直觀的字節序 

            地址低位存儲值的高位 

            地址高位存儲值的低位 

            為什么說直觀,不要考慮對應關系 

            只需要把內存地址從左到右按照由低到高的順序寫出 

            把值按照通常的高位到低位的順序寫出 

            兩者對照,一個字節一個字節的填充進去 


            例子:在內存中雙字 0x01020304(DWORD) 的存儲方式 


            內存地址 

            4000 4001 4002 4003 
            LE 04 03 02 01 
            BE 01 02 03 04 

            例子:如果我們將 0x1234abcd 寫入到以 0x0000 開始的內存中,則結果為 

                   big-endian   little-endian
            0x0000   0x12       0xcd
            0x0001   0x23       0xab
            0x0002   0xab       0x34
            0x0003   0xcd       0x12
            x86
             
            系列 CPU 都是 little-endian 的字節序 

            網絡字節順序是 TCP/IP 中規定好的一種數據表示格式,它與具體的 CPU 類型、操作系統等無關,從而可以保證數據在不同主機之間傳輸時能夠被正確解釋。網絡字節順序采用 big endian 排序方式。 


            為了進行轉換 bsd socket 提供了轉換的函數 有下面四個 
            htons 
             unsigned short 類型從主機序轉換到網絡序 
            htonl 
             unsigned long 類型從主機序轉換到網絡序 
            ntohs 
             unsigned short 類型從網絡序轉換到主機序 
            ntohl 
             unsigned long 類型從網絡序轉換到主機序 

            在使用 little endian 的系統中 這些函數會把字節序進行轉換 
            在使用 big endian 類型的系統中 這些函數會定義成空宏 


            同樣 在網絡程序開發時 或是跨平臺開發時 也應該注意保證只用一種字節序 不然兩方的解釋不一樣就會產生 bug.

            注: 

            1 
            、網絡與主機字節轉換函數 :htons ntohs htonl ntohl (s 就是 short l  long h  host n  network)
            2
             、不同的 CPU 上運行不同的操作系統,字節序也是不同的,參見下表。 

            處理器      操作系統      字節排序 
            Alpha     
            全部      Little endian
            HP-PA     NT     Little endian
            HP-PA     UNIX     Big endian
            Intelx86    
             全部      Little endian <-----x86 系統是小端字節序系統 

            Motorola680x()     
            全部      Big endian
            MIPS     NT     Little endian
            MIPS     UNIX     Big endian
            PowerPC     NT     Little endian
            PowerPC    
              NT     Big endian   <-----PPC 系統是大端字節序系統 

            RS/6000     UNIX     Big endian
            SPARC     UNIX     Big endian
            IXP1200 ARM
             
            核心      全部      Little endian

            2.

            一、字節序定義

            字節序,顧名思義字節的順序,再多說兩句就是大于一個字節類型的數據在內存中的存放順序(一個字節的數據當然就無需談順序的問題了)。

            其實大部分人在實際的開發中都很少會直接和字節序打交道。唯有在跨平臺以及網絡程序中字節序才是一個應該被考慮的問題。

            在所有的介紹字節序的文章中都會提到字節序分為兩類:Big-Endian和Little-Endian。引用標準的Big-Endian和Little-Endian的定義如下:
            a) Little-Endian就是低位字節排放在內存的低地址端,高位字節排放在內存的高地址端。
            b) Big-Endian就是高位字節排放在內存的低地址端,低位字節排放在內存的高地址端。
            c) 網絡字節序:4個字節的32 bit值以下面的次序傳輸:首先是0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit。這種傳輸次序稱作大端字節序。由于 TCP/IP首部中所有的二進制整數在網絡中傳輸時都要求以這種次序,因此它又稱作網絡字節序。比如,以太網頭部中2字節的“
             以太網幀類型”,表示后面數據的類型。對于ARP請求或應答的以太網幀類型 來說,在網絡傳輸時,發送的順序是0x08,0x06。在內存中的映象如下圖所示:
            棧底 (高地址)
            ---------------
            0x06 -- 低位 
            0x08 -- 高位
            ---------------
            棧頂 (低地址)
            該字段的值為0x0806。按照大端方式存放在內存中。

            二、高/低地址與高低字節

            首先我們要知道我們C程序映像中內存的空間布局情況:在《C專家編程》中或者《Unix環境高級編程》中有關于內存空間布局情況的說明,大致如下圖:
            ----------------------- 最高內存地址 0xffffffff
            | 棧底
            .
            .              棧
            .
            棧頂
            -----------------------
            |
            |
            /|/

            NULL (空洞)

            /|/
            |
            |
            -----------------------
                            堆
            -----------------------
            未初始化的數據
            ----------------(統稱數據段)
            初始化的數據
            -----------------------
            正文段(代碼段)
            ----------------------- 最低內存地址 0x00000000

            以上圖為例如果我們在棧上分配一個unsigned char buf[4],那么這個數組變量在棧上是如何布局的呢[注1]?看下圖:
            棧底 (高地址)
            ----------
            buf[3]
            buf[2]
            buf[1]
            buf[0]
            ----------
            棧頂 (低地址)

            現 在我們弄清了高低地址,接著來弄清高/低字節,如果我們有一個32位無符號整型0x12345678(呵呵,恰好是把上面的那4個字節buf看成一個整 型),那么高位是什么,低位又是什么呢?其實很簡單。在十進制中我們都說靠左邊的是高位,靠右邊的是低位,在其他進制也是如此。就拿 0x12345678來說,從高位到低位的字節依次是0x12、0x34、0x56和0x78。

            高低地址和高低字節都弄清了。我們再來回顧一下Big-Endian和Little-Endian的定義,并用圖示說明兩種字節序:
            以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) -- 低位
            ---------------
            棧頂 (低地址)

            在現有的平臺上Intel的X86采用的是Little-Endian,而像Sun的SPARC采用的就是Big-Endian。

            三、例子

            嵌入式系統開發者應該對Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU對操作數的存放方式是從低字節到高字節,而Big-endian模式對操作數的存放方式是從高字節到低字節。

            例如,16bit寬的數0x1234在Little-endian模式CPU內存中的存放方式(假設從地址0x4000開始存放)為:

            內存地址 存放內容
            0x4001    0x12
            0x4000    0x34

            而在Big-endian模式CPU內存中的存放方式則為:

            內存地址 存放內容
            0x4001    0x34
            0x4000    0x12

            32bit寬的數0x12345678在Little-endian模式CPU內存中的存放方式(假設從地址0x4000開始存放)為:

            內存地址 存放內容
            0x4003     0x12
            0x4002     0x34
            0x4001     0x56
            0x4000     0x78

            而在Big-endian模式CPU內存中的存放方式則為:

            內存地址 存放內容
            0x4003     0x78
            0x4002     0x56
            0x4001     0x34
            0x4000     0x12


            網絡傳輸一般采用大端序,也被稱之為網絡字節序,或網絡序IP協議中定義大端序為網絡字節序。 
            http://blog.csdn.net/zhaojiangwei102/article/details/4532184

            posted on 2012-03-07 11:13 厚積薄發 閱讀(961) 評論(0)  編輯 收藏 引用 所屬分類: 網絡編程

            導航

            <2025年6月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            統計

            常用鏈接

            留言簿

            隨筆分類

            文章分類

            文章檔案

            搜索

            最新評論

            中文精品久久久久人妻| 久久99国产综合精品女同| 欧美久久久久久午夜精品| 久久青青草原精品国产不卡| 中文字幕精品无码久久久久久3D日动漫| 99久久做夜夜爱天天做精品| 久久久久人妻一区二区三区vr| 国产精品久久久天天影视香蕉 | 亚洲人成精品久久久久| 久久精品国产久精国产| 久久久噜噜噜久久中文字幕色伊伊 | 99久久精品国产麻豆| 日韩欧美亚洲国产精品字幕久久久| 久久免费看黄a级毛片| 国产高潮国产高潮久久久91| 无码久久精品国产亚洲Av影片| 久久国产视屏| 久久国产乱子精品免费女| 一本色道久久综合狠狠躁| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 国产成人精品综合久久久久| 2020最新久久久视精品爱| 伊人久久综合成人网| 国产99久久久国产精品小说| 久久久WWW成人免费毛片| 久久免费高清视频| 狠狠色丁香婷婷久久综合不卡| 亚洲va久久久噜噜噜久久狠狠 | 亚洲国产日韩欧美久久| 欧美激情精品久久久久久| 国产精品美女久久久网AV| 久久久久夜夜夜精品国产| 久久精品国产免费一区| 国产精品天天影视久久综合网| 久久中文骚妇内射| 国产精品对白刺激久久久| 国产国产成人精品久久| 97r久久精品国产99国产精| 久久精品国产99国产电影网| 久久综合综合久久97色| 伊人久久精品线影院|