proactor服务器端数据打包问题
正如几位高手所说,数据必须要打包发送,自己定一个协议,以解包和打包现在这个过程中遇到如下难题:先贴代码上来,再慢慢看问题:
//发送函数,参数中容器fcls和objs中装的就是要传送的数据,是需要发送的数据
//设计为先发送fcls再发送objs
//初步决定4KB为一个包发送,所以涉及到打包问题,以fcls为例每个fcls前加一个包头,其中有flag和数据长度
int CommunicationServer::sendData(std::vector<FeatureClassPtr> &fcls,std::vector<Feature*> &objs)
{
//先发送fcls ,每个数据段前加一个包头,格式为:flag(f/o) + length
char packHead = "f";
for(std::vector<FeatureClassPtr>::iterator i = fcls.begin();i != fcls.end();++i)
{
//....
//得到flcs中的数据buf
//....
size_t *pb = (size_t *)(packHead+1); //写好包头中的length
*pb = buf->size();
ACE_Message_Block *mb;
ACE_NEW_RETURN(mb, ACE_Message_Block(4096), -1);
if (-1 == mb->copy((const char *)packHead,5))//写包头
{
size_t ncoun_left = mb->space();
mb->copy((const char *)packHead,ncoun_left);
initWriteStream(*mb,4096);
}
else
{
if (-1 == mb->copy((const char*)buf->begin(),buf->size())) //写具体数据
{
size_t ncount_left = mb->space();
mb->copy((const char *)buf->begin(),ncount_left);
initWriteStream(*mb,4096);
}
}
//上述代码中有很大问题,其一,把mb声明放循环里面,每循环一次,申请一个mb,显然不能达到打包的效果
//其二,把mb声明放循环外面,那当打好一个包后,又不能把它release掉,还是不能打包
//其三,先计算所有要发送的数据总长,要打包多少,然后定义一个mb 数组,一个一个用掉。。。方案看似可行,但过于复杂
请问高手,如何解决这种Proactor 的打包问题。。。。 你没有理解ACE_Message_Block的特点。此类是ACE系统的血液,它靠引用计数管理。
你的这种需求很常见的。如果不是受限的系统,图简单的话,完全可以用小的block存储,再内部cont或者link一下。
一起处理的。
非常灵活。 正如几位高手所说,数据必须要打包发送,自己定一个协议,以解包和打包
请问楼主,你说发送数据必须要打包,能说下理由么?只知其然不知其所以然是不够的。
个人观点:如果只是为了发数据,不需要打包,也不需要用message block。ACE_Message_Block是很强大,但是比简单缓冲区的使用和管理要复杂得多。它有自己的适用场合,不要为了用而用。
回复 #3 wishel 的帖子
我是异步写的,它的接口ACE_Asynch_write_stream( ACE_Message_Block * ,size_t )参数就是 message block啊,那该怎么用简单缓冲区? 我觉得这不关 message block 的事,发消息不打包,随便一个大一个小的发吗?那接收方怎么知道下一次发多大?有人说先发数据长度过去,再发数据,可是我是异步发送的啊,那万一顺序乱了,接收方怎么接? 本来就是ACE_Message_Block那当然不必再转成简单缓冲区。
不打包一样可以发,是否打包看具体需求,比如你发个文件,有必要拆包打包么?eof就是fin,收到就证明完了,大小都不需要事先通知。
异步发送的问题,只要你保证发送时的调用顺序,完成顺序就能保证(同一handle)。接收方收到的也是顺序的。
我前面的评论是针对这句话“数据必须要打包发送,自己定一个协议,以解包和打包”。
不能太绝对,不同应用场景适合不同的发送方式。
页:
[1]