diff --git a/client/client.cpp b/client/client.cpp index 5d84621..6579dba 100644 --- a/client/client.cpp +++ b/client/client.cpp @@ -190,17 +190,17 @@ bool CClient::down_task(const std::string& param) relative_path = v[1]; } auto id = std::stoi(v[0]); - if (!task_list_.count(id)) { + if (!clients_.count(id)) { TLOGE("No matched id[{}] in task list.", id); return false; } - if (task_list_[id]->id == own_id_) { + if (clients_[id]->id == own_id_) { TLOGW("You can't down your own file!!!"); return false; } - const auto& vec = task_list_[id]->files; + const auto& vec = clients_[id]->files; down_ = std::make_shared(); if (vec.empty()) { @@ -210,7 +210,7 @@ bool CClient::down_task(const std::string& param) // 开始传输文件 for (const auto& item : vec) { - if (!down_one_file(task_list_[id]->id, item, relative_path)) { + if (!down_one_file(id, item, relative_path)) { break; } std::this_thread::sleep_for(std::chrono::milliseconds(20)); @@ -301,12 +301,12 @@ bool CClient::send_files(const std::string& param) TLOGW("Have Task Downloading, Please wait....."); return false; } - if (!task_list_.count(index)) { - TLOGE("No Index Found {}.", index); + if (!clients_.count(index)) { + TLOGE("{} No Index Found {}.", __LINE__, index); return false; } - const auto& sr = task_list_[index]; + const auto& sr = clients_[index]; if (sr->id == own_id_) { TLOGW("You can't send file to yourself!!!"); return false; @@ -344,16 +344,13 @@ bool CClient::send_files(const std::string& param) return false; } -#if defined(_WIN32) - handel_ret = CCodec::ansi_to_u8(handel_ret); -#endif - list_file_ = "auto_list"; std::shared_ptr buf = std::make_shared(); buf->type_ = TYPE_REQUEST_UPDATE_LIST; - buf->data_ = new char[handel_ret.size() + 1](); - buf->len_ = std::snprintf(buf->data_, handel_ret.size() + 1, "%s", handel_ret.c_str()); - buf->tid_ = task_list_[index]->id; + CMessageInfo msg_info; + msg_info.str = handel_ret; + serialize(msg_info, &buf->data_, buf->len_); + buf->tid_ = clients_[index]->id; if (!send_frame(buf.get())) { TLOGE("Send Failed {}", __LINE__); @@ -362,24 +359,28 @@ bool CClient::send_files(const std::string& param) return true; } -bool CClient::down_one_file(const std::string& id, const std::string& file, const std::string& local_dir) +bool CClient::down_one_file(int remote_id, const std::string& file, const std::string& local_dir) { - std::string back_file(file); - std::string back_local_dir(local_dir); + if (clients_.count(remote_id) == 0) { + TLOGE("{} No Index Found {}.", __LINE__, remote_id); + return false; + } + auto client = clients_[remote_id]; + down_->cur_remote_id_ = client->id; + down_->cur_remote_file_ = file; -#ifdef _WIN32 - back_file = CCodec::u8_to_ansi(back_file); - back_local_dir = CCodec::u8_to_ansi(back_local_dir); -#endif - - down_->cur_remote_id_ = id; - down_->cur_remote_file_ = back_file; fs::path remote_file(ofen::COfPath::normalize(down_->cur_remote_file_)); - - if (back_local_dir.empty()) { + if (local_dir.empty()) { down_->cur_file_ = COfPath::to_full(remote_file.filename().string()); } else { - down_->cur_file_ = fs::path(back_local_dir).append(remote_file.filename().string()).string(); + down_->cur_file_ = fs::path(local_dir).append(remote_file.filename().string()).string(); + } + + // 这里要先检查羁绊 + if (client->uuid == uuid_ && COfPath::is_same_dir(remote_file.string(), down_->cur_file_)) { + // 处在同一个机器上的同目录下 + TLOGE("You Can't Operate File In Same Dir And In Same Machine.", down_->cur_remote_file_); + return false; } TLOGW("Start Down => {} To {}", down_->cur_remote_file_, down_->cur_file_); @@ -388,15 +389,13 @@ bool CClient::down_one_file(const std::string& id, const std::string& file, cons TLOGE("Open {} Failed.", down_->cur_file_); return false; } - - // 在这里补充 UUID - std::string uuid_file = uuid_ + "UUID" + file; // 请求下载文件 std::shared_ptr buf = std::make_shared(); buf->type_ = TYPE_OPEN_FILE; - buf->tid_ = id; - buf->data_ = new char[uuid_file.size() + 1]; - buf->len_ = std::snprintf(buf->data_, uuid_file.size() + 1, "%s", uuid_file.data()); + buf->tid_ = client->id; + CMessageInfo msg_info; + msg_info.str = file; + serialize(msg_info, &buf->data_, buf->len_); if (!send_frame(buf.get())) { TLOGE("{} request open file [{}] send failed.", __FUNCTION__, down_->cur_remote_file_); down_->cur_remote_id_.clear(); @@ -485,12 +484,12 @@ bool CClient::request_update_list(const std::string& param) TLOGW("Have Task Downloading, Please wait....."); return false; } - if (!task_list_.count(index)) { - TLOGE("No Index Found {}.", index); + if (!clients_.count(index)) { + TLOGE("{} No Index Found {}.", __LINE__, index); return false; } - const auto& sr = task_list_[index]; + const auto& sr = clients_[index]; bool local_trans = false; if (sr->id == own_id_) { TLOGW("local_trans path handle mode!!!"); @@ -573,16 +572,13 @@ bool CClient::request_update_list(const std::string& param) return false; } -#if defined(_WIN32) - handel_ret = CCodec::ansi_to_u8(handel_ret); -#endif - list_file_ = list_file_full; std::shared_ptr buf = std::make_shared(); buf->type_ = TYPE_REQUEST_UPDATE_LIST; - buf->data_ = new char[handel_ret.size() + 1](); - buf->len_ = std::snprintf(buf->data_, handel_ret.size() + 1, "%s", handel_ret.c_str()); - buf->tid_ = task_list_[index]->id; + CMessageInfo msg_info; + msg_info.str = handel_ret; + serialize(msg_info, &buf->data_, buf->len_); + buf->tid_ = clients_[index]->id; if (!send_frame(buf.get())) { TLOGE("Send Failed {}", __LINE__); @@ -593,11 +589,7 @@ bool CClient::request_update_list(const std::string& param) bool CClient::check_update_list(const std::string& content, std::map& files) { - std::string back_str(content); -#ifdef _WIN32 - back_str = CCodec::u8_to_ansi(back_str); -#endif - auto vec = COfStr::split(back_str, "\n"); + auto vec = COfStr::split(content, "\n"); bool valid = true; for (const auto& item : vec) { if (item.empty()) { @@ -616,11 +608,7 @@ bool CClient::check_update_list(const std::string& content, std::map check pass {}", pr); -#ifdef _WIN32 - files[CCodec::ansi_to_u8(vi[0])] = CCodec::ansi_to_u8(pr); -#else files[vi[0]] = pr; -#endif } return valid; } @@ -631,15 +619,24 @@ bool CClient::down_update_file(const std::map& files) buf->tid_ = list_serve_id_; down_ = std::make_shared(); bool suc = true; + + int id = -1; + for (const auto& item : clients_) { + if (item.second->id == list_serve_id_) { + id = item.first; + break; + } + } + for (const auto& item : files) { - if (!down_one_file(list_serve_id_, item.first, item.second)) { + if (!down_one_file(id, item.first, item.second)) { suc = false; break; } } if (suc) { buf->type_ = TYPE_DONE_UPDATE_LIST; - TLOGW("################## Do Task From Remote {} Done!", buf->tid_); + TLOGI("################## Do Task From Remote {} Done!", buf->tid_); } else { buf->type_ = TYPE_FAILED_UPDATE_LIST; TLOGE("################## Do Task From Remote {} Failed!", buf->tid_); @@ -678,16 +675,17 @@ bool CClient::require_dir_files(const std::string& param) int index = std::stoi(tvec[0]); std::string path = tvec[1]; - if (!task_list_.count(index)) { - TLOGE("No Index Found {}.", index); + if (!clients_.count(index)) { + TLOGE("{} No Index Found {}.", __LINE__, index); return false; } - const auto& sr = task_list_[index]; + const auto& sr = clients_[index]; std::shared_ptr buf = std::make_shared(); buf->type_ = TYPE_GET_DIRFILES; - buf->data_ = new char[path.size() + 1](); - buf->len_ = std::snprintf(buf->data_, path.size() + 1, "%s", path.c_str()); + CMessageInfo msg_info{}; + msg_info.str = path; + serialize(msg_info, &buf->data_, buf->len_); buf->tid_ = sr->id; if (!send_frame(buf.get())) { @@ -708,12 +706,12 @@ bool CClient::down_req_list(const std::string& param) std::string lists = tvec[1]; std::string local = tvec.size() > 2 ? COfPath::to_full(tvec[2]) : COfPath::to_full(""); - if (!task_list_.count(index)) { - TLOGE("No Index Found {}.", index); + if (!clients_.count(index)) { + TLOGE("{} No Index Found {}.", __LINE__, index); return false; } - const auto& sr = task_list_[index]; + const auto& sr = clients_[index]; if (sr->id == own_id_) { TLOGE("Can't Req Self Task {}.", sr->id); return false; @@ -725,12 +723,7 @@ bool CClient::down_req_list(const std::string& param) if (path.empty()) { continue; } -// down_one_file的编码为 UTF8 -#if _WIN32 - path = CCodec::ansi_to_u8(path); - local = CCodec::ansi_to_u8(local); -#endif - if (!down_one_file(sr->id, path, local)) { + if (!down_one_file(index, path, local)) { TLOGE("Down Failed {}", __LINE__); return false; } @@ -863,7 +856,7 @@ void CClient::handle_frame(CFrameBuffer* buf) break; } case TYPE_GET_LIST: { - task_list_.clear(); + clients_.clear(); CMessageInfo msg_info; if (!deserialize(buf->data_, buf->len_, msg_info)) { TLOGE("{} GetList deserialize failed.", __LINE__); @@ -881,24 +874,30 @@ void CClient::handle_frame(CFrameBuffer* buf) if (num < 20) { TLOGI("FILE ==> {}", real); } - task_list_[index]->files.push_back(real); + clients_[index]->files.push_back(real); ++num; } else { - auto a = real.find_first_of('[') + 1; - auto b = real.find_first_of(']'); - std::string str_index = real.substr(a, b - a); + auto a1 = real.find_first_of('[') + 1; + auto b1 = real.find_first_of(']'); + std::string str_index = real.substr(a1, b1 - a1); index = std::stoi(str_index); std::string backup = real; - backup.erase(0, b + 1); - auto aa = backup.find_first_of('[') + 1; - auto bb = backup.find_first_of(']'); - std::string id = backup.substr(aa, bb - aa); + backup.erase(0, b1 + 1); + auto a2 = backup.find_first_of('[') + 1; + auto b2 = backup.find_first_of(']'); + std::string id = backup.substr(a2, b2 - a2); - if (!task_list_.count(index)) { - task_list_[index] = std::make_shared(); - task_list_[index]->id = id; - task_list_[index]->uuid = msg_info.uuid; + auto a3 = real.find_last_of('[') + 1; + auto b3 = real.find_last_of(']'); + std::string uuid = real.substr(a3, b3 - a3); + + real.erase(a3 - 1, b3 - a3 + 2); + + if (!clients_.count(index)) { + clients_[index] = std::make_shared(); + clients_[index]->id = id; + clients_[index]->uuid = uuid; } if (num < 20) { TLOGD("============================================"); @@ -932,28 +931,25 @@ void CClient::handle_frame(CFrameBuffer* buf) break; } case TYPE_GET_DIRFILES: { - std::string path(buf->data_, buf->len_); -#ifdef _WIN32 - path = CCodec::u8_to_ansi(path); -#endif - TLOGI("Get Dir Files {}", path); + CMessageInfo msg_info; + if (!deserialize(buf->data_, buf->len_, msg_info)) { + TLOGE("{} GetDirFiles deserialize failed.", __LINE__); + break; + } + TLOGI("{} Get Dir Files: {}", buf->fid_, msg_info.str); std::string err; std::string out; - if (!get_dir_files(path, out, err)) { + if (!get_dir_files(msg_info.str, out, err)) { TLOGE("Get Dir Files Failed. {}", err); buf->type_ = TYPE_GET_DIRFILES_FAILED; delete[] buf->data_; - buf->data_ = new char[err.size() + 1]; - buf->len_ = std::snprintf(buf->data_, err.size() + 1, "%s", err.c_str()); + msg_info.str = err; } else { -#ifdef _WIN32 - out = CCodec::ansi_to_u8(out); -#endif buf->type_ = TYPE_GET_DIRFILES_DONE; delete[] buf->data_; - buf->data_ = new char[out.size() + 1]; - buf->len_ = std::snprintf(buf->data_, out.size() + 1, "%s", out.c_str()); + msg_info.str = out; } + serialize(msg_info, &buf->data_, buf->len_); std::swap(buf->tid_, buf->fid_); if (!send_frame(buf)) { TLOGE("Send Failed {}.", __LINE__); @@ -962,16 +958,21 @@ void CClient::handle_frame(CFrameBuffer* buf) break; } case TYPE_GET_DIRFILES_FAILED: { - std::string err(buf->data_, buf->len_); - TLOGE("Get {} Dir Files Failed. {}", buf->fid_, err); + CMessageInfo msg_info; + if (!deserialize(buf->data_, buf->len_, msg_info)) { + TLOGE("{} GetDirFiles deserialize failed.", __LINE__); + break; + } + TLOGE("Get {} Dir Files Failed. {}", buf->fid_, msg_info.str); break; } case TYPE_GET_DIRFILES_DONE: { - std::string out(buf->data_, buf->len_); -#ifdef _WIN32 - out = CCodec::u8_to_ansi(out); -#endif - auto vec = COfStr::split(out, "\n"); + CMessageInfo msg_info; + if (!deserialize(buf->data_, buf->len_, msg_info)) { + TLOGE("{} GetDirFiles deserialize failed.", __LINE__); + break; + } + auto vec = COfStr::split(msg_info.str, "\n"); TLOGD("$$$$$$$$$ START $$$$$$$$$"); for (const auto& item : vec) { std::string real = COfStr::trim(item); @@ -993,32 +994,15 @@ void CClient::handle_frame(CFrameBuffer* buf) } case TYPE_OPEN_FILE: { std::string keys{}; + CMessageInfo msg_info; + if (!deserialize(buf->data_, buf->len_, msg_info)) { + TLOGE("{} OpenFile deserialize failed.", __LINE__); + break; + } { std::lock_guard lock(mutex_); up_[buf->fid_] = std::make_shared(); - std::string uuid_file = std::string(buf->data_, buf->len_); -#ifdef _WIN32 - uuid_file = CCodec::u8_to_ansi(uuid_file); -#endif - // 拿出 UUID - auto uuid_index = uuid_file.find("UUID"); - if (uuid_index == std::string::npos) { - TLOGE("UUID Not Found."); - buf->type_ = TYPE_OPEN_FAILED; - std::swap(buf->tid_, buf->fid_); - if (!send_frame(buf)) { - TLOGE("Send Failed {}.", __LINE__); - } - break; - } - up_[buf->fid_]->cur_remote_uuid_ = uuid_file.substr(0, uuid_index); - uuid_file.erase(0, uuid_index + 4); - up_[buf->fid_]->cur_file_ = uuid_file; - - // 这里做校验 - if (up_[buf->fid_]->cur_remote_uuid_ == uuid_) { - } - + up_[buf->fid_]->cur_file_ = msg_info.str; up_[buf->fid_]->file_.open(up_[buf->fid_]->cur_file_, std::ios::in | std::ios::binary); up_[buf->fid_]->trans_state_ = TRANS_REDAY; if (!up_[buf->fid_]->file_.is_open()) { @@ -1080,8 +1064,12 @@ void CClient::handle_frame(CFrameBuffer* buf) TLOGW("Update Busy......, Ignore {}", buf->fid_); buf->type_ = TYPE_BUSY_UPDATE_LIST; } else { - std::string content(buf->data_, buf->len_); - if (check_update_list(content, files)) { + CMessageInfo msg_info; + if (!deserialize(buf->data_, buf->len_, msg_info)) { + TLOGE("{} GetList deserialize failed.", __LINE__); + break; + } + if (check_update_list(msg_info.str, files)) { buf->type_ = TYPE_CONFIRM_UPDATE_LIST; } else { buf->type_ = TYPE_UNCONFIRM_UPDATE_LIST; diff --git a/client/client.h b/client/client.h index 9b652e2..163f84e 100644 --- a/client/client.h +++ b/client/client.h @@ -30,7 +30,6 @@ enum TransState { struct TransInfomation { std::string cur_remote_id_; std::string cur_remote_file_; - std::string cur_remote_uuid_; std::string cur_file_; std::fstream file_{}; uint16_t permissions{}; @@ -54,7 +53,7 @@ public: bool up_task(const std::string& param); bool cancel_task(); bool send_files(const std::string& param); - bool down_one_file(const std::string& id, const std::string& file, const std::string& local_dir = ""); + bool down_one_file(int remote_id, const std::string& file, const std::string& local_dir = ""); void report_trans_ret(TransState state, const std::string& key = ""); bool request_update_list(const std::string& param); bool check_update_list(const std::string& content, std::map& files); @@ -90,7 +89,7 @@ private: bool downloading_{false}; asio::io_context io_context_; std::shared_ptr client_; - std::map> task_list_; + std::map> clients_; std::shared_ptr down_; std::vector ths_; std::map> up_; diff --git a/ofen b/ofen index f6bc83b..9313801 160000 --- a/ofen +++ b/ofen @@ -1 +1 @@ -Subproject commit f6bc83b0de92adb1d5f8de7f1235c1a222c6b84b +Subproject commit 931380105b6ec88ce86912f3139c5b1fb2fb280b diff --git a/server/server.cpp b/server/server.cpp index 1e75016..98ee398 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -75,29 +75,39 @@ void CTcpServer::stop() client_threads_.clear(); } -std::vector CTcpServer::get_clients() -{ - std::vector result; - std::shared_lock lock(cli_mut_); - for (const auto& item : client_map_) { - TaskList t; - t.id_ = item.first; - t.task_ = item.second->task_; - t.task_time_ = item.second->task_time_; - t.online_time_ = item.second->online_time_; - result.push_back(t); - } - return result; -} - void CTcpServer::get_client_list(CMessageInfo& msg_info) { - auto vec = get_clients(); + struct TmpInfo { + std::string id; + std::string online_time; + std::string uuid; + std::string task; + uint64_t timestamp; + }; + std::vector vec; std::string msg; + + { + std::shared_lock lock(cli_mut_); + for (const auto& item : client_map_) { + TmpInfo tmp; + tmp.id = item.first; + tmp.online_time = item.second->online_time_; + tmp.timestamp = item.second->timestamp; + tmp.uuid = item.second->uuid; + tmp.task = item.second->task_; + vec.push_back(tmp); + } + } + + // 排序 vec 根据 client->timestamp + std::sort(vec.begin(), vec.end(), + [](const TmpInfo& a, const TmpInfo& b) { return a.timestamp < b.timestamp; }); + int index = 1; for (const auto& item : vec) { - msg.append(fmt::format("[{}][{}][{}]", index, item.id_, item.online_time_)); - auto files = COfStr::split(item.task_, "|"); + msg.append(fmt::format("[{}][{}][{}][{}]", index, item.id, item.online_time, item.uuid)); + auto files = COfStr::split(item.task, "|"); for (const auto& file : files) { msg.append("\n" + file); } @@ -127,9 +137,6 @@ void CTcpServer::trans_data(CFrameBuffer* buf) TLOGI("[{}] GetList.", buf->fid_); 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."); @@ -231,6 +238,7 @@ void CTcpServer::accept_client() auto cache = std::make_shared(); cache->socket_ = socket; cache->online_time_ = OfUtil::now_time(); + cache->timestamp = OfUtil::get_timestamp_ms(); cache->last_active_time_ = std::chrono::high_resolution_clock::now(); client_map_[client_key] = cache; can = true; diff --git a/server/server.h b/server/server.h index 9f1dd5e..478c34b 100644 --- a/server/server.h +++ b/server/server.h @@ -19,15 +19,10 @@ struct ClientCache { std::string uuid{}; std::string task_time_{}; std::string online_time_{}; + uint64_t timestamp{}; high_c last_active_time_; FrameType cur_type_{TYPE_DEFAULT}; }; -struct TaskList { - std::string id_{}; - std::string task_{}; - std::string task_time_{}; - std::string online_time_{}; -}; class CTcpServer { @@ -40,7 +35,6 @@ public: void stop(); private: - std::vector get_clients(); void get_client_list(CMessageInfo& msg_info); private: