服务器设计笔记(1)-----消息的封装

    消息的封装方式有多中,比如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. 这样的类不是一次能设计好的,需要在后续的开发过程中持续的改进。  


上一篇:nazo.io 通关记录


下一篇:最急救助(【CCF】NOI Online能力测试3 入门组)