OpenBuffer用于解析网络数据流,解决TCP粘包问题

OpenBuffer是一个针对网络数据流设计的库,解决TCP粘包问题,支持多平台,包括Windows、Linux、Mac、iOS和Android。通过CMake构建,在VS和Xcode中可编译运行。库提供序列化和反序列化功能,包括整数和可变长整数。示例代码展示了如何使用OpenBuffer处理和解析HTTP报文。
摘要由CSDN通过智能技术生成

OpenBuffer

OpenBuffer 用于读写解析二进制流,解决TCP粘包问题,针对网络数据流而设计。

https://github.com/OpenMiniServer

跨平台支持

Windows、linux、Mac、iOS、Android等跨平台设计

编译和执行

请安装cmake工具,用cmake可以构建出VS或者XCode工程,就可以在vs或者xcode上编译运行。
源代码:https://github.com/OpenMiniServer/openbuffer
https://github.com/OpenMiniServer/openbuffer

git clone https://github.com/OpenMiniServer/openbuffer
cd ./openbuffer
mkdir build
cd build
cmake ..
#如果是win32,在该目录出现openbuffer.sln,点击它就可以启动vs写代码调试
make
./test

全部源文件

  • src/openbuffer.h
  • src/openbuffer.cpp

技术特点

OpenBuffer的技术特点:

  1. 对于添加数据push操作,使用节点链表来管理内存。每次push数据,数据存储到一个节点上,超过节点容量,就会创建新的节点进行存储。
  2. 从OpenBuffer读取数据,先把全部节点上的数据进行合并,存储到连续的内存上,然后释放对应节点的内存。
  3. 支持读写固定长度整数和不固定长度整数。

1.序列化与反序列化

支持整数,可变长整数序列化。采用小端编码。

#include <assert.h>
#include <string.h>
#include <string>
#include <vector>
#include "openbuffer.h"

using namespace open;

int main()
{
    OpenBuffer openBuffer(256);

    char data[256] = "Hello OpenBuffer!";
    const std::string str = "Hello OpenLinyou!";
    
    size_t len = strlen(data);
    openBuffer.push(&len, sizeof(len));
    openBuffer.push(data, len);
 
    len = str.size();
    openBuffer.pushUInt32(len);
    openBuffer.push(str.data(), len);

    openBuffer.pushUInt16(1616);
    openBuffer.pushUInt32(3232);
    openBuffer.pushUInt64(6464);

    openBuffer.pushVInt32(0x79);
    openBuffer.pushVInt32(0x80);
    openBuffer.pushVInt32(0x4000);
    openBuffer.pushVInt32(0x10000000);

    openBuffer.pushVInt64(0x10000001);

    std::vector<char> vectData;
    len = 0;
    openBuffer.pop(&len, sizeof(len));
    vectData.resize(len);
    openBuffer.pop(vectData.data(), len);
    assert(memcmp(vectData.data(), data, len) == 0);
    
    char ret[256] = {};
    uint32_t len1 = 0;
    openBuffer.popUInt32(len1);
    openBuffer.pop(ret, len1);
    assert(str == ret);
    
    unsigned short u16 = 0;
    openBuffer.popUInt16(u16);
    assert(u16 == 1616);

    uint32_t u32 = 0;
    openBuffer.popUInt32(u32);
    assert(u32 == 3232);
    uint64_t u64 = 0;
    openBuffer.popUInt64(u64);
    assert(u64 == 6464);


    uint64_t v32 = 0;
    openBuffer.popVInt64(v32);
    assert(v32 == 0x79);

    uint64_t v32_1 = 0;
    openBuffer.popVInt64(v32_1);
    assert(v32_1 == 0x80);

    uint64_t v32_2 = 0;
    openBuffer.popVInt64(v32_2);
    assert(v32_2 == 0x4000);

    uint64_t v32_3 = 0;
    openBuffer.popVInt64(v32_3);
    assert(v32_3 == 0x10000000);

    uint64_t v64 = 0;
    openBuffer.popVInt64(v64);
    assert(v64 == 0x10000001);
    
    return 0;
}

2.解析网络数据包

模拟socket数据包,解析http报文。解决HTTP沾包问题。

#include <assert.h>
#include <string.h>
#include <string>
#include <vector>
#include "openbuffer.h"

using namespace open;

int main()
{
    std::vector<std::string> datas = {
        "HTTP/1.1 200 OK@&Connection: keep-alive@&Content-Type: application/x-javascript@&",
        "Date: Sat, 18 Mar 2023 08:11:44 GMT@&Strict-Transport-Security: max-age=31536000@&Traceco",
        "de: 24764974122629742602031816@&Vary: Accept-Encoding@&"
    };
    std::string body = "Hello OpenBuffer!!Hello OpenBuffer!!";
    datas.push_back("content-length:" + std::to_string(body.size()) + "@&");
    datas.push_back("@&" + body);
    datas.push_back("@&");
    OpenBuffer openBuffer;
    for (size_t x = 0; x < 10000; x++)
    {
        openBuffer.clear();
        bool isHeader = true;
        size_t k = 0;
        std::string head;
        for (size_t i = 0; i < datas.size(); ++i)
        {
            openBuffer.push(datas[i].data(), datas[i].size());
            if (isHeader)
            {
                unsigned char* tmp = openBuffer.data();
                for (; k < openBuffer.size() - 3; k++)
                {
                    //find @&@&
                    if (tmp[k] == '@' && tmp[k + 1] == '&' && tmp[k + 2] == '@' && tmp[k + 3] == '&')
                        break;
                }
                if (k >= openBuffer.size() - 3) continue;

                k += 4;
                openBuffer.pop(head, k);
                isHeader = false;
            }
        }
        std::string test = body + "@&";
        std::string buffer;
        buffer.append((const char*)openBuffer.data(), openBuffer.size());
        assert(test == buffer);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值