• <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 厚積薄發 閱讀(962) 評論(0)  編輯 收藏 引用 所屬分類: 網絡編程

            導航

            <2025年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            統計

            常用鏈接

            留言簿

            隨筆分類

            文章分類

            文章檔案

            搜索

            最新評論

            国产精品一区二区久久精品无码| 偷窥少妇久久久久久久久| 99久久精品国内| 日本久久久精品中文字幕| 久久国产综合精品五月天| 精品久久久久久无码不卡| 精品无码久久久久国产| 色综合久久久久综合99| 69久久精品无码一区二区| 久久午夜夜伦鲁鲁片免费无码影视 | 久久午夜福利无码1000合集| 久久超碰97人人做人人爱| 久久93精品国产91久久综合| 久久久久人妻精品一区| 欧美久久亚洲精品| 国产叼嘿久久精品久久| 国产精品久久久久AV福利动漫| 三级韩国一区久久二区综合| 国产高潮国产高潮久久久91| 97久久精品无码一区二区天美| 亚洲国产成人精品久久久国产成人一区二区三区综 | 久久精品成人影院| www.久久热.com| 久久久久亚洲精品无码蜜桃| 久久精品成人欧美大片| 一本久久免费视频| 一级做a爰片久久毛片看看| 久久本道久久综合伊人| 亚洲嫩草影院久久精品| 国产精品对白刺激久久久| 国产午夜精品久久久久免费视| 一本久道久久综合狠狠爱| 亚洲精品成人久久久| 一个色综合久久| 久久久久av无码免费网| 亚洲色欲久久久综合网东京热| 精品久久久久久国产| 亚洲国产另类久久久精品黑人| 亚洲人成网亚洲欧洲无码久久| 久久综合亚洲鲁鲁五月天| 人妻丰满AV无码久久不卡|