消息的封装方式有多中,比如xml,json等,但是我依然觉得使用拼数据的方式最简单,也最节省带宽。比如我们处理一个逻辑就可以这样处理了:
int cast_net(MessageBlock &mb)
{
int area_id,lvl;
mv >> area >> lvl;
//逻辑处理
//....
MessageBlock re_mb;
re_mb << item_id << item_sum;
return this->respond_to_client(re_mb);
}
在之前公司的时候,使用的是ace的ACE_Message_Block,来到了新的公司,重新封装了ACE_Message_Block。 很多地方学习了ACE的设计。比如 wr_ptr(),rd_ptr()等。
MessageBlock.h 文件
/*
* MessageBlock.h
*
* Created on: Aug 11, 2012
* Author: archy_yu
*/
#ifndef MESSAGEBLOCK_H_
#define MESSAGEBLOCK_H_
#include <TlvPackage.h>
#include <string>
class MessageBlock
{
public:
MessageBlock(int =0);
/*
MessageBlock(short tag,short len);
MessageBlock(TLVEntity paraTlvEntity);
*/
MessageBlock(MessageBlock &mb);
/*
MessageBlock(char* msg,int len);
MessageBlock(std::string str);
*/
virtual ~MessageBlock();
MessageBlock& operator << (const char &value);
MessageBlock& operator << (const short &value);
MessageBlock& operator << (const int &value);
MessageBlock& operator << (const char* ss);
MessageBlock& operator >> (char &value);
MessageBlock& operator >> (short &value);
MessageBlock& operator >> (int &value);
MessageBlock& operator >> (char* ss);
void set_len();
int get_len();
char* wr_ptr();
char* rd_ptr();
int Capacity();
private:
int wr_position;
int rd_position;
int capacity;
int len;
char* data;
};
#endif /* MESSAGEBLOCK_H_ */
MessageBlock.cpp文件
/*
* MessageBlock.cpp
*
* Created on: Aug 11, 2012
* Author: archy_yu
*/
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "MessageBlock.h"
MessageBlock::MessageBlock(int n)
{
wr_position = 0;
rd_position = 0;
len = 0;
this->data = (char *)calloc(n > 0 ? n : 1024,sizeof(char));
this->capacity = n > 0 ? n : 1024;
}
/*
MessageBlock::MessageBlock(short tag,short len)
{
this->dataindex = 0;
this->len = len;
this->data = (char *)calloc(len,sizeof(char));
if(this->data == NULL)
{
//error
}
}
MessageBlock::MessageBlock(TLVEntity paraTlvEntity)
{
this->dataindex = 0;
this->len = paraTlvEntity.Length;
this->data = (char* )calloc(paraTlvEntity.Length,sizeof(char));
if(this->data == NULL)
{
//error
}
memcpy(this->data,paraTlvEntity.Value,paraTlvEntity.Length);
}
*/
MessageBlock::MessageBlock(MessageBlock &mb)
{
this->data = mb.data;
this->len = mb.len;
this->capacity = mb.capacity;
this->rd_position = mb.rd_position;
this->wr_position = mb.wr_position;
}
/*
MessageBlock::MessageBlock(char* msg,int len)
{
this->data = (msg);
this->len = len;
this->dataindex = 0;
}
MessageBlock::MessageBlock(std::string str)
{
this->data = const_cast<char* >(str.c_str());
this->len = str.size();
this->dataindex = 0;
}
*/
MessageBlock::~MessageBlock()
{
// TODO Auto-generated destructor stub
free(this->data);
}
MessageBlock& MessageBlock::operator << (const char &value)
{
if((wr_position + sizeof(char)) > this->capacity)
{
this->data = (char* )realloc(this->data,wr_position + sizeof(char));
if(this->data == NULL)
{
return *this;
}
this->capacity = this->wr_position + sizeof(char);
}
*((char* )(this->data + wr_position )) = value;
wr_position += sizeof(char);
len = wr_position ;
return *this;
}
MessageBlock& MessageBlock::operator <<(const short &value)
{
if((wr_position + sizeof(short)) > this->len)
{
this->data = (char* )realloc(this->data,wr_position + sizeof(short));
if(this->data == NULL)
{
return *this;
}
this->capacity = this->wr_position + sizeof(short);
}
*((short* )( this->data + wr_position )) = value;
wr_position += sizeof(short);
len = wr_position;
return *this;
}
MessageBlock& MessageBlock::operator <<(const int &value)
{
if((wr_position + sizeof(int)) > this->len)
{
this->data = (char *)realloc(this->data,wr_position + sizeof(int));
if(this->data == NULL)
{
return *this;
}
this->capacity = this->wr_position + sizeof(int);
}
*((int* )( this->data + wr_position )) = value;
wr_position += sizeof(int);
this->len = wr_position;
return *this;
}
MessageBlock& MessageBlock::operator <<(const char* ss)
{
short len = strlen(ss);
if((wr_position + 2 + len) > this->len)
{
this->data = (char *)realloc(this->data,wr_position + 2 + strlen(ss));
if(this->data == NULL)
{
return *this;
}
this->capacity = this->wr_position + 2 + strlen(ss);
}
*((short* )(this->data + wr_position)) = len;
wr_position += sizeof(len);
this->len = wr_position;
memcpy(this->data + wr_position,ss,len);
wr_position += len;
this->len = wr_position;
return *this;
}
MessageBlock& MessageBlock::operator >>(char &value)
{
if((rd_position + sizeof(char)) > this->len)
{
return *this;
}
value = *((char* )(this->data + rd_position ));
rd_position += sizeof(char);
return *this;
}
MessageBlock& MessageBlock::operator >>(short &value)
{
if((rd_position + sizeof(short)) > this->len)
{
return *this;
}
value = *((short* )(this->data + rd_position ));
rd_position += sizeof(short);
return *this;
}
MessageBlock& MessageBlock::operator >>(int &value)
{
if((rd_position + sizeof(short)) > this->len)
{
return *this;
}
value = *((int* )(this->data + rd_position));
rd_position += sizeof(int);
return *this;
}
MessageBlock& MessageBlock::operator >>(char* ss)
{
short len = *((short* )(this->data + rd_position));
if( (this->rd_position + sizeof(len) + len) > (this->len) )
{
return *this;
}
rd_position += sizeof(len);
memcpy(ss,this->data + rd_position,len);
ss[len] = '\0';
rd_position += len;
return *this;
}
char* MessageBlock::wr_ptr()
{
return this->data + wr_position;
}
char* MessageBlock::rd_ptr()
{
return this->data + rd_position;
}
int MessageBlock::Capacity()
{
return this->capacity;
}
void MessageBlock::set_len()
{
(*(short *)(this->data)) = this->wr_position;
}
int MessageBlock::get_len()
{
return this->len;}
需要说明的几点:
1. linux服务器一般都是小端的设计,但是flash在使用ByteArray的时候就要注意大端小端的使用了。
2. 这样的类不是一次能设计好的,需要在后续的开发过程中持续的改进。