Skip to content

Commit 64a2cf1

Browse files
committed
Merge branch 'dev_tcp_client_chengxin' into 'feature_tcp_client'
【ADD】基于tcp长连接的封包和拆包基础方法 See merge request server/openapi/openapi-cpp-sdk!12
2 parents 3be5d00 + ff27d2e commit 64a2cf1

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#ifndef PUSH_FRAME_SERIALIZE_H
2+
#define PUSH_FRAME_SERIALIZE_H
3+
#include <vector>
4+
#include <string>
5+
6+
namespace TIGER_API
7+
{
8+
class PushFrameEncoder
9+
{
10+
public:
11+
static std::vector<unsigned char> encode_frame(const std::string& packed_frame);
12+
};
13+
14+
class PushFrameDecoder
15+
{
16+
public:
17+
PushFrameDecoder() = default;
18+
~PushFrameDecoder() = default;
19+
20+
bool push_byte(unsigned char value);
21+
uint64_t get_frame_size() const;
22+
23+
private:
24+
uint64_t decode_varint();
25+
std::vector<unsigned char> frame_header_buffer_;
26+
uint64_t frame_len_ = 0;
27+
};
28+
29+
}
30+
#endif //PUSH_FRAME_SERIALIZE_H
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#include "tigerapi/push_socket/push_frame_serialize.h"
2+
#include <boost/endian/conversion.hpp>
3+
4+
std::vector<unsigned char> TIGER_API::PushFrameEncoder::encode_frame(const std::string& packed_frame)
5+
{
6+
if (packed_frame.empty())
7+
{
8+
return std::vector<unsigned char>();
9+
}
10+
11+
size_t pack_size = packed_frame.size();
12+
std::vector<unsigned char> pack_array;
13+
14+
unsigned char bits = pack_size & 0x7F;
15+
pack_size >>= 7;
16+
while (pack_size)
17+
{
18+
unsigned char header_byte = 0x80 | bits;
19+
pack_array.push_back(/*boost::endian::native_to_big(header_byte)*/header_byte);
20+
bits = pack_size & 0x7F;
21+
pack_size >>= 7;
22+
}
23+
24+
pack_array.push_back(/*boost::endian::native_to_big(bits)*/bits);
25+
pack_array.insert(pack_array.end(), packed_frame.begin(), packed_frame.end());
26+
return pack_array;
27+
}
28+
29+
bool TIGER_API::PushFrameDecoder::push_byte(unsigned char value)
30+
{
31+
//逐个字节压入缓冲区(使用大端序列)
32+
frame_header_buffer_.push_back(/*boost::endian::native_to_big(value)*/value);
33+
if (!(value & 0x80))
34+
{
35+
//完整读取到包长度
36+
frame_len_ = decode_varint();
37+
frame_header_buffer_.clear();
38+
//frame头部已经读取完毕
39+
return true;
40+
}
41+
//frame头部还有数据,需要继续独取头部数据
42+
return false;
43+
}
44+
45+
uint64_t TIGER_API::PushFrameDecoder::get_frame_size() const
46+
{
47+
return frame_len_;
48+
}
49+
50+
uint64_t TIGER_API::PushFrameDecoder::decode_varint()
51+
{
52+
const uint32_t mask = (1U << 32) - 1; // 32位掩码
53+
uint32_t result = 0;
54+
int shift = 0;
55+
56+
for (const unsigned char& b : frame_header_buffer_)
57+
{
58+
result |= (static_cast<uint32_t>(b & 0x7F) << shift);
59+
shift += 7;
60+
if (shift >= 64)
61+
{
62+
throw std::runtime_error("Too many bytes when decoding varint.");
63+
}
64+
}
65+
66+
result &= mask; // 应用32位掩码
67+
return result;
68+
}

0 commit comments

Comments
 (0)