当前位置:编程学习 > C/C++ >>

最简单的TCP网络封包解包(补充)-序列化

如若描述或者代码当中有谬误之处,还望指正。

将数据能够在TCP中进行传输的两种方法
1.直接拷贝struct就可以了;
2.序列化。

拷贝Struct存在的问题
1.不能应付可变长类型的数据,比如STL中的那些容器,当然,STL的容器归根到底就是一个class,他们的长度都是不确定的;
2.内存对齐的问题,Windows默认的对齐是4字节,如果不去刻意关闭掉对齐的话,那么可能会多出不少没必要的字节数,但是如果关闭了,内存拷贝又会慢一些。

序列化是怎么序列化的?
其实很简单,我们使用一个uint8类型的数组,假设我们这里有一个uint16类型的数据,那么我们就把它拷贝进去uint8的数组里面,那么它就占了两个元素。这是最基本的规则。具体请参考代码里面的ByteBuffer::append()方法。而那些class神马的,我们只要按照自己设定的规则顺序拷贝进去就可以了。这个在BytBuffer里面默认支持了常用的STL容器,可以参看代码。

类型定义
#if defined(_MSC_VER)
    //
    // Windows/Visual C++
    //
    typedef signed __int8            int8;
    typedef unsigned __int8            uint8;
    typedef signed __int16            int16;
    typedef unsigned __int16        uint16;
    typedef signed __int32            int32;
    typedef unsigned __int32        uint32;
    typedef signed __int64            int64;
    typedef unsigned __int64        uint64;
#endif有的类型的长度会因硬件或者操作系统而异,如果直接使用c++关键字中的类型定义可能会出现问题。因此,需要自己定义以上这样的类型。利用宏去适配各个操作系统或者硬件平台。

ByteBuffer的代码
/**///////////////////////////////////////////////////////////////////////////
/// 字节流缓冲类,可以进行序列化和解序列化操作,并且可以缓冲字节流数据。
//////////////////////////////////////////////////////////////////////////
class ByteBuffer
{
public:
    const static size_t DEFAULT_SIZE = 0x1000;

    ByteBuffer()
        : mReadPos(0)
        , mWritePos(0)
    {
        mStorage.reserve(DEFAULT_SIZE);
    }

    ByteBuffer(size_t res)
        : mReadPos(0)
        , mWritePos(0)
    {
        mStorage.reserve(res);
    }

    ByteBuffer(const ByteBuffer &buf)
        : mReadPos(buf.mReadPos)
        , mWritePos(buf.mWritePos)
        , mStorage(buf.mStorage)
    {}

    /**///////////////////////////////////////////////////////////////////////////
public:
    void clear()
    {
        mStorage.clear();
        mReadPos = mWritePos = 0;
    }

    template <typename T>
        void append(T value)
    {
        append((uint8*)&value, sizeof(value));
    }

    template <typename T>
        void put(size_t pos, T value)
    {
        put(pos, (uint8*)&value, sizeof(value));
    }

    /**///////////////////////////////////////////////////////////////////////////
public:
    ByteBuffer& operator<<(bool value)
    {
        append<char>((char)value);
        return *this;
    }
    ByteBuffer& operator<<(uint8 value)
    {
        append<uint8>(value);
        return *this;
    }
    ByteBuffer& operator<<(uint16 value)
    {
        append<uint16>(value);
        return *this;
    }
    ByteBuffer& operator<<(uint32 value)
    {
        append<uint32>(value);
        return *this;
    }
    ByteBuffer& operator<<(uint64 value)
    {
        append<uint64>(value);
        return *this;
    }

    ByteBuffer& operator<<(int8 value)
    {
        append<int8>(value);
        return *this;
    }
    ByteBuffer& operator<<(int16 value)
    {
        append<int16>(value);
        return *this;
    }
    ByteBuffer& operator<<(int32 value)
    {
        append<int32>(value);
        return *this;
    }
    ByteBuffer& operator<<(int64 value)
    {
        append<int64>(value);
        return *this;
    }

    ByteBuffer& operator<<(float value)
    {
        append<float>(value);
        return *this;
    }
    ByteBuffer& operator<<(double value)
    {
        append<double>(value);
        return *this;
    }
    ByteBuffer& operator<<(time_t value)
    {
        append<time_t>(value);
        return *this;
    }

    ByteBuffer& operator<<(const std::string& value)
    {
        append((uint8 const *)value.c_str(), value.length());
        append((uint8)0);
        return *this;
    }
    ByteBuffer& operator<<(const char* str)
    {
        append( (uint8 const *)str, str ? strlen(str) : 0);
        append((uint8)0);
        return *this;
    }

    /**//////////////////////////////////////////////

补充:软件开发 , C语言 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,