1. 程式人生 > >編程-Byte order & Bit order

編程-Byte order & Bit order

work htons short end 概念 hosts UC fin ttl

看到比特序和字節序放在一起被提及,想必就已經填補了概念拼圖裏面缺失的那一塊了,這一塊正是比特序。

一直以來,接觸到最多的就是字節序:

大端字節序:big-endian byte order;

小端字節序:little-endian byte order;

網絡字節序:network byte order;

大小端字節序轉換:

/* 大端字節序 */
i = (data[3]<<0) | (data[2]<<8) | (data[1]<<16) | (data[0]<<24);
/* 小端字節序 */
i = (data[0]<<0) | (data[1
]<<8) | (data[2]<<16) | (data[3]<<24);

網絡字節序轉換:

 uint32_t htonl(uint32_t hostlong); 
 uint16_t htons(uint16_t hostshort); 
 uint32_t ntohl(uint32_t netlong); 
 uint16_t ntohs(uint16_t netshort); 

是不是很熟悉?

見多識廣的想必也見過這個(from linux kernel include/uapi/linux/tcp.h ):

struct tcphdr {
    __be16    source;
    __be16    dest;
    __be32    seq;
    __be32    ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD) __u16 res1:4, doff:4, fin:1, syn:1, rst:1, psh:1, ack:1, urg:1, ece:1, cwr:1; #elif defined(__BIG_ENDIAN_BITFIELD) __u16 doff:4, res1:4, cwr:1, ece:1, urg:
1, ack:1, psh:1, rst:1, syn:1, fin:1; #else #error "Adjust your <asm/byteorder.h> defines" #endif __be16 window; __sum16 check; __be16 urg_ptr; };

明顯跟我們之前見到的以字節為單位進行轉換的不同,這裏是以bit為單位;

不深究的話,可能看到BIG_ENDIAN和LITTLE_ENDIAN還有下面的 "Adjust your <asm/byteorder.h> defines" ,就覺得是byte order的變種,也理解成byteorder就行了。

如果知道bit order的概念,就知道這是兩個不同的概念了。

PS. 關於上面tcphdr的定義:

1. 條件編譯的宏是 :

__LITTLE_ENDIAN_BITFIELD
__BIG_ENDIAN_BITFIELD

意思是比特域的大小端,和字節序大小端是分開的:

__LITTLE_ENDIAN
__BIG_ENDIAN 

2. 下面的#error又說是byteorder,

#error    "Adjust your <asm/byteorder.h> defines"

是否矛盾?這裏的情況是,linux kernel中把字節序和比特序都放在byteorder.h裏面定義。這裏只說調整這個頭文件的定義,並沒有說調整字節序的定義,所以應該沒問題。

include/uapi/linux/byteorder/big_endian.h 中的定義:

#ifndef _UAPI_LINUX_BYTEORDER_BIG_ENDIAN_H
#define _UAPI_LINUX_BYTEORDER_BIG_ENDIAN_H

#ifndef __BIG_ENDIAN
#define __BIG_ENDIAN 4321
#endif
#ifndef __BIG_ENDIAN_BITFIELD
#define __BIG_ENDIAN_BITFIELD
#endif

編程-Byte order & Bit order