ACD_CDR编译时的4个宏、下面4个宏在ACE编译时默认都是关闭的。
如果要让自己的ACE库有相关的能力需要在config.h中定义以下宏
ACE_InputCDR 相关的宏
ACE_CDR_IGNORE_ALIGNMENT
该宏让CDR Stream忽略输入流的字节对其,全部按单字节对其。
如果没有设置该宏,ACE采用8个字节对输入流进行默认对其。
ACE_DISABLE_SWAP_ON_READ
该宏静止把输入流赋值给多字节数据变量(2、4、8)时静止高低字节序的交换。
默认情况下该宏关闭、也就是ACE_InputCDR会对字节序进行交换。
一般情况下我们不需要定义该宏、除非我们的系统中所有的网络设备都是同一个字节体系的。否则必须关闭该宏。
ACE_OutputCDR 相关的宏
ACE_LACKS_CDR_ALIGNMENT
该宏打开后、忽略把多字节数据写入输出流时忽略字节对其、而是采用单字节对其的方式写入。
默认ACE关闭该宏、此时ACE在写入时会根据写入数据的字节自动调整。也就是写入Short、Int等类型时
起始地址调整为 sizeof( datatype) 的整数倍数。即 startWriteAddre % sizeof( DataType) == 0
ACE_ENABLE_SWAP_ON_WRITE
该宏打开在写入多字节数据类型时,自动进行字节序的交换。
关于字节序交换的问题:
1) ACE_InputCDR 、ACE_OutputCDR 何时会对读取或者写入的多字节数据进行字节序交换呢?
ACE_InputCDR 宏ACE_DISABLE_SWAP_ON_READ关闭时,而且其byte_order与本机的字节序不一致时.
ACE_OutputCDR 宏打开释,而且ACE_OutputCDR对象的byte_order 与本机器的字节序不一致时.
关于PC编程的问题:
1. 由于网络通信一般采用BIG字节序/也叫做网络字节序.
2. 我们使用的PC机或者嵌入式系统可能使用BIG字节序也可能使用LITTEN(小字节序)
3. 当我们的编程环境为LITTEN(小字节序)时,请继续关注下面的问题.
ACE_InputCDR InputStream(NetWorkBuffer) ; // 假设 NetWorkBuffer 是从网络上接受到的字节流
InputStream.reset_byte_order(ACE_CDR::BYTE_ORDER_BIG_ENDIAN);// 我们必须明确的指定我们现在在处理的数据的字节流的类型.
ACE_OutputCDR OutputStream(LocalBuffer); // 假设 LocalBuffer 是我们要发送到网络对等体的数据缓存区
OutputStream.reset_byte_order(ACE_CDR::BYTE_ORDER_BIG_ENDIAN); // 由于网络字节序采用的是BIG,所以我们要明确的指定.
4. 何时可以不比关注字节序问题.
4.1 通信的双方都是相同的字节序/而且内部约定好采用了同一种字节序时.
如果你是一个老手/你一定不会忽略字节序问题的/否则随着通信系统的复杂度的提高/你到时会头大的,而且这样的习惯从网络编程的角度来说是极其不道德的.
ACE_CDR 对输入输出流使用俩组不同宏来控制/而且其默认规则都不太一样,对刚刚开始使用ACE_CDR进行网络编程的人都需要折腾一番的.
2组宏来控制ACE的网络字节流可能使为了提高控制灵活性吧--还是要问问ACE的设计者的意图?
#define ACE_CDR_IGNORE_ALIGNMENT
/*
#ifdef ACE_DISABLE_SWAP_ON_READ
#undef ACE_DISABLE_SWAP_ON_READ # 取消该宏的定义. 定义该宏就歇菜了...
#endif
*/
#define ACE_LACKS_CDR_ALIGNMENT
#define ACE_ENABLE_SWAP_ON_WRITE