字节序,又称为端序和尾序(Endianness)。它指存放多字节数据的字节顺序,例如:整数(short、int等)在内存中存放的方式和网络传输的传输顺序。
大端字节序(big-endian),又称大尾序:最高有效位(MSB)存储在最低内存地址处。最直观的字节序,地址低位存储值的高位,地址高位存储只的地位。
小端字节序(little-endian),又称小尾序:最低有效位(LSB)存储在最低内存地址处。符合人的思维,地址地位存储值的低位,地址高位存储值的高位。
网络传输一般采用大端字节序,又称为网络字节序或网络序。
示例:在内存中32位整数0X01020304的存储方式。
内存地址 |
0x0000 |
0x0001 |
0x0002 |
0x0003 |
|
Little-Endian |
0x01 |
0x02 |
0x03 |
0x04 |
X86机器 |
Big-Endian |
0x04 |
0x03 |
0x03 |
0x01 |
网络传输 |
注:采用Big-Endian方式存储数据方便人从字面理解数据,Little-Endian数据比较难以理解,它主要从方便CPU处理数据,提供计算机效率考虑的。
主机字节序转换成网络字节序函数:
u_long htonl(u_long hostlongvalue);
u_short htons(u_short hostshortvalue);
网络字节序转换成主机字节序函数:
u_long ntohl(u_long netlongvalue);
u_short hotns(u_short netshortvalue);
注:在Windows平台中字节序转换函数代码中没有进行字节序的检测,只是简单的进行了高低位的转换,这是因为Windows平台都使用LE字节序的缘故。
将一个IPV4地址的字符串转换成一个无符号整数函数:
u_long inet_addr(const char *cp);
其中:cp—一个以IP地址字符串,例如:192.168.1.1。
当IP地址为255.255.255.255视为无效,返回值为0xffffffff(-1)。
当IP地址转换错误时(例如:不符合IP地址格式)返回INADDR_NONE(-1)。
示例:u_long ipval = inet_addr(“127.0.0.1”);
将一个无符号整数转换为IP地址字符串函数:
char *inet_ntoa(struct in_addr in);
其中:in — 表示主机地址的结构
注意inet_ntoa()返回的字符串存放在套接字接口实现所分配的内存中,应用程序不应该假设内存是如何分配的,因此它不是一个线程安全的函数。
返回值:无错误发生返回一个字符串指针,否则返回NULL指针。
示例:
struct in_addr in;
in.s_addr = 1234567; // it’s net longvalue;
char *ipaddr = inet_ntoa(in);
inet_aton()函数与inet_ntoa()作用相反,Windows中不能使用,只能用于类UNIX平台上。
将字符串转换为网络地址函数:
int inet_pton(int af, const char *src,void *dst);
其中:af—地址族,例如:AF_INET,AF_INET6等。
src—地址字符串,
dst—in6_addr或in_addr指针,根据af来确定。
该函数支持IPV4和IPV6地址字符串的转换。
将二进制格式转化为地址字符串函数:
const char *inet_ntop(int af, constvoid *src, char* dst, socklen_t cnt);
其中:af—地址族
src— 二进制地址,一般为in_addr或in6_addr指针;
dst—地址字符串指针
cnt—存放地址字符串的内存长度。
返回值:如果dst无法存储地址字符串返回NULL空指针。
inet_ntop和inet_pton是一对二进制和字符串地址之间相互转化的函数。