linux下的位元組序問題總結

來源:互聯網
上載者:User

1. 位元組順序概念

位元組順序是指占記憶體多於一個位元組類型的資料在記憶體中的存放順序,通常有小端、大端兩種位元組順序。

大端對齊:記憶體的低地址位存放著高位元據;

小端對齊:記憶體的低地址位存放著低位元據;

舉個例子,記憶體中兩個連續位元組中的資料為0x12 0x34,表示一個short,如果是大端對齊,這個數為0x1234;如果是小端對齊,則這個數為0x3412。


2. 測試

在我的開發機器上(linux2.6.16)上,經過測試,為小端對齊,轉化為網路位元組序之後,為大端對齊。

測試程式很簡單:

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <arpa/inet.h>int main(){        int16_t x = 1;        if(*(char*)&x == 1)                printf("little endian\n");        else                printf("big endian\n");        int16_t y = ntohs(x);        if(*(char*)&y == 1)                printf("net little endian\n");        else                printf("net big endian\n");}

3. linux api介面

網路位元組序與本地位元組序的轉化,glibc提供了4個介面,man的結果如下:

BYTEORDER(3)   Linux Programmer's Manual  BYTEORDER(3)NAME       htonl,  htons,  ntohl,  ntohs - convert values between host and network       byte orderSYNOPSIS       #include <arpa/inet.h>       uint32_t htonl(uint32_t hostlong);       uint16_t htons(uint16_t hostshort);       uint32_t ntohl(uint32_t netlong);       uint16_t ntohs(uint16_t netshort);DESCRIPTION       The htonl() function converts the unsigned integer hostlong  from  host       byte order to network byte order.       The htons() function converts the unsigned short integer hostshort from       host byte order to network byte order.       The ntohl() function converts the unsigned integer netlong from network       byte order to host byte order.       The  ntohs() function converts the unsigned short integer netshort from       network byte order to host byte order.       On the i386 the host  byte  order  is  Least  Significant  Bytefirst,       whereasthe  network byte order, as used on the Internet, is Most Sig-       nificant Byte first.

Glibc還提供了一組介面,直接轉化本地位元組序到大端或者小端對齊。(man查看的結果是glibc2.9之後開始支援的,我這邊的機器上還沒有)

ENDIAN(3)   Linux Programmer's Manual     ENDIAN(3)NAME       htobe16, htole16, be16toh, le16toh, htobe32, htole32, be32toh, le32toh,       htobe64, htole64, be64toh, le64toh - convert values  between  host  and       big-/little-endian byte orderSYNOPSIS       #define _BSD_SOURCE       /* See feature_test_macros(7) */       #include <endian.h>       uint16_t htobe16(uint16_t host_16bits);       uint16_t htole16(uint16_t host_16bits);       uint16_t be16toh(uint16_t big_endian_16bits);       uint16_t le16toh(uint16_t little_endian_16bits);       uint32_t htobe32(uint32_t host_32bits);       uint32_t htole32(uint32_t host_32bits);       uint32_t be32toh(uint32_t big_endian_32bits);       uint32_t le32toh(uint32_t little_endian_32bits);       uint64_t htobe64(uint64_t host_64bits);       uint64_t htole64(uint64_t host_64bits);       uint64_t be64toh(uint64_t big_endian_64bits);       uint64_t le64toh(uint64_t little_endian_64bits);

4. 64位整型,本地與網路位元組序的轉化

如果是int64_t或者uint64_t,沒有ntoh系列介面支援,只能通過htobe64這種介面來實現本地位元組序到網路位元組序的轉換(從2中的測試中,可以得到網路位元組序為大端對齊)。

如果glibc的版本不支援htobe系列的介面,那麼只能自己寫轉換程式了,一個簡單的轉換程式如下:

uint64_t htonll(uint64_t v) {    union { uint32_t lv[2]; uint64_t llv; } u;    u.lv[0] = htonl(v >> 32);    u.lv[1] = htonl(v & 0xFFFFFFFFULL);    return u.llv;}uint64_t ntohll(uint64_t v) {    union { uint32_t lv[2]; uint64_t llv; } u;    u.llv = v;    return ((uint64_t)ntohl(u.lv[0]) << 32) | (uint64_t)ntohl(u.lv[1]);}

5. 參考文章

http://stackoverflow.com/questions/809902/64-bit-ntohl-in-c

http://cpp.ezbty.org/import_doc/linux_manpage/be64toh.3.html

http://www.unix.com/man-page/Linux/3/ntohl/

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.