diff --git a/client/client.cpp b/client/client.cpp index b18e45a..5d84621 100644 --- a/client/client.cpp +++ b/client/client.cpp @@ -259,15 +259,14 @@ bool CClient::up_task(const std::string& param) return false; } -#ifdef _WIN32 - msg = CCodec::ansi_to_u8(msg); -#endif + CMessageInfo msg_info; + msg_info.uuid = uuid_; + msg_info.str = msg; std::shared_ptr buf = std::make_shared(); buf->type_ = TYPE_UP_LIST; - buf->data_ = new char[msg.size() + 1]; - std::memset(buf->data_, 0x0, msg.size() + 1); - buf->len_ = std::snprintf(buf->data_, msg.size() + 1, "%s", msg.data()); + + serialize(msg_info, &buf->data_, buf->len_); return send_frame(buf.get()); } @@ -844,8 +843,9 @@ void CClient::get_id() { auto* bf = new CFrameBuffer(); bf->type_ = TYPE_GET_ID; - bf->data_ = new char[uuid_.size() + 1]; - bf->len_ = std::snprintf(bf->data_, uuid_.size() + 1, "%s", uuid_.c_str()); + CMessageInfo msg_info; + msg_info.uuid = uuid_; + serialize(msg_info, &bf->data_, bf->len_); send_frame(bf); delete bf; } @@ -864,8 +864,12 @@ void CClient::handle_frame(CFrameBuffer* buf) } case TYPE_GET_LIST: { task_list_.clear(); - std::string source(buf->data_, buf->len_); - auto vec = COfStr::split(source, "\n"); + CMessageInfo msg_info; + if (!deserialize(buf->data_, buf->len_, msg_info)) { + TLOGE("{} GetList deserialize failed.", __LINE__); + break; + } + auto vec = COfStr::split(msg_info.str, "\n"); int index = -1; size_t num = 0; for (const auto& item : vec) { @@ -875,11 +879,7 @@ void CClient::handle_frame(CFrameBuffer* buf) } if (real.find('[') == std::string::npos) { if (num < 20) { -#ifdef _WIN32 - TLOGI("FILE ==> {}", CCodec::u8_to_ansi(real)); -#else TLOGI("FILE ==> {}", real); -#endif } task_list_[index]->files.push_back(real); ++num; @@ -898,6 +898,7 @@ void CClient::handle_frame(CFrameBuffer* buf) if (!task_list_.count(index)) { task_list_[index] = std::make_shared(); task_list_[index]->id = id; + task_list_[index]->uuid = msg_info.uuid; } if (num < 20) { TLOGD("============================================"); diff --git a/client/client.h b/client/client.h index 540648f..9b652e2 100644 --- a/client/client.h +++ b/client/client.h @@ -15,6 +15,7 @@ using namespace ofen; struct DownClientInfo { std::vector files; + std::string uuid; std::string id; }; diff --git a/server/server.cpp b/server/server.cpp index e2f831b..1e75016 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -90,9 +90,8 @@ std::vector CTcpServer::get_clients() return result; } -void CTcpServer::get_client_list(CFrameBuffer** buf) +void CTcpServer::get_client_list(CMessageInfo& msg_info) { - CFrameBuffer* tbuf = *buf; auto vec = get_clients(); std::string msg; int index = 1; @@ -105,9 +104,7 @@ void CTcpServer::get_client_list(CFrameBuffer** buf) msg.append("\n"); ++index; } - tbuf->data_ = new char[msg.size() + 1]; - std::memset(tbuf->data_, 0x0, msg.size() + 1); - tbuf->len_ = std::snprintf(tbuf->data_, msg.size() + 1, "%s", msg.data()); + msg_info.str = msg; } void CTcpServer::trans_data(CFrameBuffer* buf) @@ -128,16 +125,26 @@ void CTcpServer::trans_data(CFrameBuffer* buf) switch (buf->type_) { case TYPE_GET_LIST: { TLOGI("[{}] GetList.", buf->fid_); - get_client_list(&buf); + CMessageInfo msg_info; + get_client_list(msg_info); + if (fcli) { + msg_info.uuid = fcli->uuid; + } + serialize(msg_info, &buf->data_, buf->len_); if (fcli && !send_frame(fcli->socket_, buf)) { TLOGE("GetList send failed."); } break; } case TYPE_UP_LIST: { - std::string file_list = std::string(buf->data_, buf->len_); + CMessageInfo msg_info; + if (!deserialize(buf->data_, buf->len_, msg_info)) { + TLOGE("{} GetList deserialize failed.", __LINE__); + break; + } if (fcli) { - fcli->task_ = file_list; + fcli->task_ = msg_info.str; + fcli->uuid = msg_info.uuid; fcli->task_time_ = OfUtil::now_time(); } break; @@ -287,6 +294,19 @@ void CTcpServer::th_client(const std::shared_ptr& socket, delete frame; continue; } + if (frame->type_ == TYPE_GET_ID) { + CMessageInfo msg_info; + if (!deserialize(frame->data_, frame->len_, msg_info)) { + TLOGE("{} GetId deserialize failed.", __LINE__); + delete frame; + continue; + } + std::unique_lock lock(cli_mut_); + if (client_map_.count(client_key)) { + auto& cli = client_map_[client_key]; + cli->uuid = msg_info.uuid; + } + } frame->fid_ = client_key; // 直接转发,不加入缓存。 trans_data(frame); diff --git a/server/server.h b/server/server.h index 0b8e04e..9f1dd5e 100644 --- a/server/server.h +++ b/server/server.h @@ -16,6 +16,7 @@ struct ClientCache { CMutBuffer buffer_{}; std::array tmp_buf_{}; std::string task_{}; + std::string uuid{}; std::string task_time_{}; std::string online_time_{}; high_c last_active_time_; @@ -40,7 +41,7 @@ public: private: std::vector get_clients(); - void get_client_list(CFrameBuffer** buf); + void get_client_list(CMessageInfo& msg_info); private: void trans_data(CFrameBuffer* buf); diff --git a/util/util.cpp b/util/util.cpp index 09163b9..c893ff6 100644 --- a/util/util.cpp +++ b/util/util.cpp @@ -1,6 +1,8 @@ #include "util.h" + #include #include +#include #include CTransProtocal::CTransProtocal() = default; @@ -127,4 +129,166 @@ CFrameBuffer::~CFrameBuffer() { delete[] data_; len_ = 0; -} \ No newline at end of file +} + +void serialize(const CMessageInfo& msg_info, char** out_buf, int& len) +{ + CMessageInfo info(msg_info); + info.cmd = localtou8(info.cmd); + info.uuid = localtou8(info.uuid); + info.str = localtou8(info.str); + info.o = localtou8(info.o); + + // 计算总长度 + len = sizeof(int) * 4 + info.cmd.size() + info.uuid.size() + info.str.size() + info.o.size(); + *out_buf = new char[len]; // 分配内存(调用方负责释放) + + char* ptr = *out_buf; + + // 序列化 cmd + int cmd_size = static_cast(info.cmd.size()); + memcpy(ptr, &cmd_size, sizeof(int)); + ptr += sizeof(int); + memcpy(ptr, info.cmd.data(), cmd_size); + ptr += cmd_size; + + // 序列化 uuid + int uuid_size = static_cast(info.uuid.size()); + memcpy(ptr, &uuid_size, sizeof(int)); + ptr += sizeof(int); + memcpy(ptr, info.uuid.data(), uuid_size); + ptr += uuid_size; + + // 序列化 str + int str_size = static_cast(info.str.size()); + memcpy(ptr, &str_size, sizeof(int)); + ptr += sizeof(int); + memcpy(ptr, info.str.data(), str_size); + ptr += str_size; + + // 序列化 o + int o_size = static_cast(info.o.size()); + memcpy(ptr, &o_size, sizeof(int)); + ptr += sizeof(int); + memcpy(ptr, info.o.data(), o_size); +} + +bool deserialize(const char* data, int len, CMessageInfo& msg_info) +{ + CMessageInfo info; + const char* ptr = data; + int remaining = len; + + // 反序列化 cmd + if (remaining < static_cast(sizeof(int))) { + return false; + } + + int cmd_size; + memcpy(&cmd_size, ptr, sizeof(int)); + ptr += sizeof(int); + remaining -= sizeof(int); + if (remaining < cmd_size) { + return false; + } + + info.cmd.assign(ptr, cmd_size); + ptr += cmd_size; + remaining -= cmd_size; + + // 反序列化 uuid + if (remaining < static_cast(sizeof(int))) { + return false; + } + + int uuid_size; + memcpy(&uuid_size, ptr, sizeof(int)); + ptr += sizeof(int); + remaining -= sizeof(int); + if (remaining < uuid_size) { + return false; + } + + info.uuid.assign(ptr, uuid_size); + ptr += uuid_size; + remaining -= uuid_size; + + // 反序列化 str + if (remaining < static_cast(sizeof(int))) { + return false; + } + + int str_size; + memcpy(&str_size, ptr, sizeof(int)); + ptr += sizeof(int); + remaining -= sizeof(int); + if (remaining < str_size) { + return false; + } + + info.str.assign(ptr, str_size); + ptr += str_size; + remaining -= str_size; + + // 反序列化 o + if (remaining < static_cast(sizeof(int))) { + return false; + } + int o_size; + memcpy(&o_size, ptr, sizeof(int)); + ptr += sizeof(int); + remaining -= sizeof(int); + if (remaining < o_size) { + return false; + } + info.o.assign(ptr, o_size); + + info.cmd = u8tolocal(info.cmd); + info.uuid = u8tolocal(info.uuid); + info.str = u8tolocal(info.str); + info.o = u8tolocal(info.o); + msg_info = info; + + return true; +} + +std::string u8tolocal(const std::string& str) +{ +#ifdef _WIN32 + return CCodec::u8_to_ansi(str); +#else + return str; +#endif +} + +std::string localtou8(const std::string& str) +{ +#ifdef _WIN32 + return CCodec::ansi_to_u8(str); +#else + return str; +#endif +} + +CMessageInfo::CMessageInfo(const CMessageInfo& info) +{ + if (&info == this) { + return; + } + cmd = info.cmd; + uuid = info.uuid; + str = info.str; + o = info.o; +} + +CMessageInfo& CMessageInfo::operator=(const CMessageInfo& info) +{ + if (&info == this) { + return *this; + } + cmd = info.cmd; + uuid = info.uuid; + str = info.str; + o = info.o; + return *this; +} diff --git a/util/util.h b/util/util.h index f954288..c6027fe 100644 --- a/util/util.h +++ b/util/util.h @@ -41,6 +41,22 @@ enum FrameType : int16_t { TYPE_GET_DIRFILES_FAILED, }; +// 此结构体成员顺序不可变动,涉及到序列化反序列化。 +struct CMessageInfo { + CMessageInfo() = default; + CMessageInfo(const CMessageInfo& info); + CMessageInfo& operator=(const CMessageInfo& info); + std::string cmd; + std::string uuid; + std::string str; + std::string o; +}; + +void serialize(const CMessageInfo& msg_info, char** out_buf, int& len); +bool deserialize(const char* data, int len, CMessageInfo& msg_info); +std::string u8tolocal(const std::string& str); +std::string localtou8(const std::string& str); + using namespace ofen; class CFrameBuffer { @@ -99,27 +115,31 @@ inline std::string now_str() template void TLOGI(const std::string& format, Args&&... args) { fc_lock_print(); - std::cout << ConsoleColor::Green << fmt::format(now_str() + format, std::forward(args)...) << std::endl; + std::cout << ConsoleColor::Green << fmt::format(now_str() + format, std::forward(args)...) + << std::endl; fc_unlock_print(); } template void TLOGW(const std::string& format, Args&&... args) { fc_lock_print(); - std::cout << ConsoleColor::Yellow << fmt::format(now_str() + format, std::forward(args)...) << std::endl; + std::cout << ConsoleColor::Yellow << fmt::format(now_str() + format, std::forward(args)...) + << std::endl; fc_unlock_print(); } template void TLOGE(const std::string& format, Args&&... args) { fc_lock_print(); - std::cout << ConsoleColor::Red << fmt::format(now_str() + format, std::forward(args)...) << std::endl; + std::cout << ConsoleColor::Red << fmt::format(now_str() + format, std::forward(args)...) + << std::endl; fc_unlock_print(); } template void TLOGD(const std::string& format, Args&&... args) { fc_lock_print(); - std::cout << ConsoleColor::Cyan << fmt::format(now_str() + format, std::forward(args)...) << std::endl; + std::cout << ConsoleColor::Cyan << fmt::format(now_str() + format, std::forward(args)...) + << std::endl; fc_unlock_print(); } \ No newline at end of file