編程-Byte order & Bit order
阿新 • • 發佈:2018-06-07
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