使用ACE_CDR类进行网络编解码(5-3)
时间:2010-10-25 来源:ronat
在缺省情况下,ACE_InputCDR和ACE_OutputCDR这两个类是不处理紧缩的,统一按4字节对齐。即小于4字节的数据类型
压进去后都占4个字节。这样做主要是处于效率的考虑。32位的CPU在处理按4字节对齐的数据时最快,不需要再处理额外的偏移。
但这样明显不符合我们前面描述的情况,我们不希望编码后的数据f中留有空洞。要解决这个问题我们需要在config.h文件中再添加一行:
这样数据在编码时就会按实际的大小进行紧缩。注意修改了config.h文件后要重新编译ACE。
我们可以看一下CNPv1第四章的例子代码,这里存在一个不够严谨的地方。日志消息的消息头由一个布尔变量指示所用的编码字节序,以及一个
unsigned long指示后面消息体的长度。布尔变量虽然只占1字节,但是由于没有定义上述的宏,编码后也占用了4个。例子中的代码在编码日志
消息时消息头和消息体是分别编码的,然后集中发送(使用了sendv_n)。 这里的问题是在代码中写死了消息头的长度为8字节。在缺省情况下布尔和整型都是4字节,没有错。但是一旦定义了上述的宏以后,布尔变量
在编码后只占1字节,整个消息头的有效部分就只有5字节了,后面跟着3个字节未定义,然后再是消息体。解码的代码是顺序依次往后解。在定义
了上面宏的情况下,没有跳过那3个未定义的字节,因此解出来的消息体都错位了。大家可以在定义了上述宏,并重新编译了ACE后,跑一下那个
例子就会发现解码时会出错。 简单的解决方法就是在解码时,解完头后显式的跳过那三个字节。最正确的解决方法是不要假设数据在编码后占的大小,只管顺序的压,
顺序的解。只要保证两端用的是同一套编译的ACE库就OK了。 到此基本上就达到我们的要求了。但是还有一个值得注意的问题,就是ACE_OutputCDR类会对它使用的buffer进行一次边界调整。
我们在后面再描述这个问题。
压进去后都占4个字节。这样做主要是处于效率的考虑。32位的CPU在处理按4字节对齐的数据时最快,不需要再处理额外的偏移。
但这样明显不符合我们前面描述的情况,我们不希望编码后的数据f中留有空洞。要解决这个问题我们需要在config.h文件中再添加一行:
#define ACE_LACKS_CDR_ALIGNMENT |
unsigned long指示后面消息体的长度。布尔变量虽然只占1字节,但是由于没有定义上述的宏,编码后也占用了4个。例子中的代码在编码日志
消息时消息头和消息体是分别编码的,然后集中发送(使用了sendv_n)。 这里的问题是在代码中写死了消息头的长度为8字节。在缺省情况下布尔和整型都是4字节,没有错。但是一旦定义了上述的宏以后,布尔变量
在编码后只占1字节,整个消息头的有效部分就只有5字节了,后面跟着3个字节未定义,然后再是消息体。解码的代码是顺序依次往后解。在定义
了上面宏的情况下,没有跳过那3个未定义的字节,因此解出来的消息体都错位了。大家可以在定义了上述宏,并重新编译了ACE后,跑一下那个
例子就会发现解码时会出错。 简单的解决方法就是在解码时,解完头后显式的跳过那三个字节。最正确的解决方法是不要假设数据在编码后占的大小,只管顺序的压,
顺序的解。只要保证两端用的是同一套编译的ACE库就OK了。 到此基本上就达到我们的要求了。但是还有一个值得注意的问题,就是ACE_OutputCDR类会对它使用的buffer进行一次边界调整。
我们在后面再描述这个问题。
相关阅读 更多 +