socket编程“网络字节顺序”和“主机字节顺序”

1.大小端模式

  在socket编程前,有必要知道大小端模式。大小端模式是指计算机内存中数据存放的模式,由CPU决定,与操作系统无关。大端模式(Big-endian,是指数据的高字节保存在内存的低地址中,数据的低字节保存在内存的高地址中,这种存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;与我们的阅读习惯一致。小端模式(Little-endian),是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。

  大端模式CPU代表是IBM Power PC,小端模式CPU代表是Intel X86、ARM。

1.1 大小的模式存储内容

  以0x12345678数据为例,两种模式在内存中的存储情况。

内存地址 小端模式存储内容 大端模式存储内容
0x0000 0x78 0x12
0x0001 0x56 0x34
0x0002 0x34 0x56
0x0003 0x12 0x78

1.2 大小端CPU判断

  可以通过执行一段程序来判断一个CPU的是大端还是小端模式。利用C语言共用体(联合体)中的几种不同类型的变量存放在同一段内存单元中的特点,可以用联合体快速实现判断大小端模式。

void bl_checkt(void)
{
	union
	{
		int  a;		
		char b;  
	}bl;
	
	bl.a=0x01;
	if (bl.b==0x01)
		printf("Little endian");
	else
		printf("Big endian");
}

1.3 大小端转换

#define BL16(x)	 ((((x) & 0x00ffUL) << 8) | (((x) & 0xff00UL) >> 8))
#define BL32(x)	 ((((x) & 0x000000ffUL) << 24) | \
                 (((x) & 0x0000ff00UL) <<  8) | \
                 (((x) & 0x00ff0000UL) >>  8) | \
                 (((x) & 0xff000000UL) >> 24))

2.网络字节顺序和主机字节顺序

  在socket网络编程中,有两个基本是术语是必须掌握的,网络字节顺序(NBO,Network Byte Order)和主机字节顺序(HBO,Host Network Order)。

  网络字节顺序,NBO是网络数据在传输中的规定的数据格式,从高到低位顺序存储,即低字节存储在高地址,高字节存储在低地址;即“大端模式”。网络字节顺序可以避免不同主机字节顺序的差异。

  主机字节顺序,HBO则与机器CPU相关,数据的存储顺序由CPU决定。

3.常用转换函数

  socket编程中经常会用到4个网络字节顺序与本地字节顺序之间的转换函数:htons()、ntohl()、 ntohs()、htons()。

 htonl()--"Host to Network Long"	长整型数据主机字节顺序转网络字节顺序
 ntohl()--"Network to Host Long"	长整型数据网络字节顺序转主机字节顺序
 htons()--"Host to Network Short"  	短整型数据主机字节顺序转网络字节顺序
 ntohs()--"Network to Host Short"  	短整型数据网络字节顺序转主机字节顺序

3.1 函数实现原型

  函数实现,即为文章开头的大小端转换。

#define htons(x)	(u16_t)BL16(x)
#define ntohs(x)	(u16_t)BL16(x)
#define htonl(x)	(u32_t)BL32(x)
#define ntohl(x)	(u32_t)BL32(x)
posted @ 2019-01-13 00:26  Acuity  阅读(180)  评论(0编辑  收藏  举报