无符号单字节 byte ,数据上表示是0x10 ,2位。
◆ 多字节基本类型,涉及到字节序little-endian和big-endian问题。(0x 01 02 0A 或 0x 0A 02 01)
主机字节序:由CPU确定多字节类型数据在内存中的存放顺序,我们用的IntelCPU是little-endian。通常这是机器内部事物,但如果涉及到网络通信就不是了。
JAVA字节序:JAVA虚拟机中的多字节类型数据在虚拟机中的存放顺序。JAVA虚拟机存储的字节流是big-endian。
网络字节序:网络传送的数据按Internet标准是big-endian解析的。和JAVA虚拟机(注意是机器不是语言)相同,和IntelCPU相反。
这里有一段W. Richard Stevens的代码,用于判断字节序
#include <stdio.h>
#include <stdlib.h>
/*
* return value:
* 1 big-endian
* 2 little-endian
* 3 unknow
* 4 sizeof( unsigned short int ) != 2
*/
static int byte_order ( void )
{
union
{
unsigned short int s;
unsigned char c[ sizeof ( unsigned short int ) ];
} un;
un.s = 0x0201;
if ( 2 == sizeof ( unsigned short int ) )
{
if ( ( 2 == un.c[0] ) && ( 1 == un.c[1] ) )
{
puts ( "big-endian" );
return ( 1 );
}
else if ( ( 1 == un.c[0] ) && ( 2 == un.c[1] ) )
{
puts ( "little-endian" );
return ( 2 );
}
else
{
puts ( "unknow" );
return ( 3 );
}
}
else
{
printf ( "sizeof( unsigned short int ) = %u\n" , ( unsigned int ) sizeof (unsigned short int ) );
return ( 4 );
}
return ( 3 );
} /* end of byte_order */
|
◆ 数据对齐 (因为结构体的组织)
32位机CPU的数据线为32位,因此地址线只接受4的倍数的地址。数据对齐,是指WORD类型数据总是存放在2倍数的地址,DWORD类型数据总是存放在4倍数的地址,大于32位的类型数据也总是存放在4倍数的地址。目的是存取一个类型数据,存取的次数尽量少。
值得注意的是C++里的struct结构体内部分量的对齐。(在移植程序时需要特别考虑,写网络程序也很重要):
设置结构体字段的偏移量对齐,,如果设置的对齐模数小于最大字段的倍数,则以设置的模数为准,如设置为1,字段之间不会有任何空隙(实际上是压缩了结构体)。
当设置为为8、16时(浪费7b):
◆ 与对齐相关的一些字符串操作,memcpy、memcmp等,在asm实现的时候,把字符串的对齐部分,作为int,CPU一次存取4个byte来拷贝比较。
总结:
字节序与网络传输相关,为此有几个ANSI C宏;
内存对齐可以通过编译器选项和语句设置 #paragram pack(n);
即使是struct,网络传输时也不能直接“拷一堆比特”,更别提类了。