#include "util.h" #include #include #include CTransProtocal::CTransProtocal() = default; CTransProtocal::~CTransProtocal() = default; /* 【 transm TCP 数据协议 】 header 2 char: 0xFF 0xFE type 2 char: mark 1 char: from 32 char: to 32 char: len 4 char: data xxxxx: tail 2 char: 0xFF 0xFF */ CFrameBuffer* CTransProtocal::parse(CMutBuffer& buffer) { CFrameBuffer* result = nullptr; unsigned char header[] = {0xFF, 0xFE}; unsigned char tail[] = {0xFF, 0xFF}; // 如果超出 1MB的内容都无法解析成功,则认为是有无效客户端参与链接。 auto cur_len = static_cast(buffer.get_len()); if (cur_len > MAX_FRAME_SIZE) { buffer.clear(); // 这里故意延迟。 std::this_thread::sleep_for(std::chrono::seconds(600)); return result; } int find = buffer.index_of((const char*)header, sizeof(header)); if (find < 0) { return result; } // reinterpret_cast 的指针转换直接访问内存可能导致未对齐问题(某些架构下) int16_t type{}; char mark{}; int32_t len{}; std::memcpy(&type, buffer.get_data() + find + 2, sizeof(type)); std::memcpy(&mark, buffer.get_data() + find + 2 + 2, sizeof(mark)); std::memcpy(&len, buffer.get_data() + find + 2 + 2 + 1 + 32 + 32, sizeof(len)); int32_t tail_index = find + 2 + 2 + 1 + 32 + 32 + 4 + len; if (buffer.get_len() - 2 < tail_index || len < 0) { return result; } if (std::memcmp(buffer.get_data() + tail_index, tail, sizeof(tail)) != 0) { return result; } result = new CFrameBuffer(); if (len > 0) { result->data_ = new char[len](); } result->len_ = len; result->fid_ = std::string(buffer.get_data() + find + 2 + 2 + 1); result->tid_ = std::string(buffer.get_data() + find + 2 + 2 + 1 + 32); result->mark_ = mark; result->type_ = static_cast(type); if (len > 0) { std::memcpy(result->data_, buffer.get_data() + find + 2 + 2 + 1 + 4 + 32 + 32, len); } buffer.remove_of(0, tail_index + 2); return result; } bool CTransProtocal::pack(CFrameBuffer* buf, char** out_buf, int& len) { if (buf == nullptr) { return false; } if (buf->data_ == nullptr) { buf->len_ = 0; } unsigned char header[] = {0xFF, 0xFE}; unsigned char tail[] = {0xFF, 0xFF}; len = buf->len_ + 75; *out_buf = new char[len]{}; std::memset(*out_buf, 0x0, len); std::memcpy(*out_buf, header, 2); std::memcpy(*out_buf + 2, &buf->type_, 2); std::memcpy(*out_buf + 2 + 2, &buf->mark_, 1); if (!buf->fid_.empty()) { std::memcpy(*out_buf + 2 + 2 + 1, buf->fid_.data(), buf->fid_.size()); } if (!buf->tid_.empty()) { std::memcpy(*out_buf + 2 + 2 + 1 + 32, buf->tid_.data(), buf->tid_.size()); } std::memcpy(*out_buf + 2 + 2 + 1 + 32 + 32, &buf->len_, 4); if (buf->data_ != nullptr) { std::memcpy(*out_buf + 2 + 2 + 1 + 32 + 32 + 4, buf->data_, buf->len_); } std::memcpy(*out_buf + len - 2, tail, 2); return true; } void CTransProtocal::display_progress(float percent) { if (percent > 1.0 || percent < 0.0) { return; } const int barWidth = 38; int pos = static_cast(barWidth * percent); std::cout << "["; for (int i = 0; i < barWidth; ++i) { if (i < pos) { std::cout << "="; } else if (i == pos) { std::cout << ">"; } else { std::cout << " "; } } // \r 回到行首 std::cout << "] " << int(percent * 100.0f) << " %\r"; std::cout.flush(); } CFrameBuffer::CFrameBuffer() = default; CFrameBuffer::~CFrameBuffer() { delete[] data_; len_ = 0; }