From 654b637e7f7b2467d2548a8ee84220b5d3b27472 Mon Sep 17 00:00:00 2001 From: taynpg Date: Tue, 7 Jan 2025 12:07:43 +0800 Subject: [PATCH] =?UTF-8?q?add=EF=BC=9A=E6=B7=BB=E5=8A=A0=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E8=BF=9B=E5=BA=A6=EF=BC=8C=E5=BE=85=E8=BF=9B=E4=B8=80?= =?UTF-8?q?=E6=AD=A5=E6=B5=8B=E8=AF=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/client.cpp | 64 +++++++++++++++++++++++++++++++++-------------- client/client.h | 5 +++- ofen | 2 +- util/util.cpp | 24 ++++++++++++++++++ util/util.h | 4 ++- 5 files changed, 77 insertions(+), 22 deletions(-) diff --git a/client/client.cpp b/client/client.cpp index ec3cf0c..2dd74c9 100644 --- a/client/client.cpp +++ b/client/client.cpp @@ -24,15 +24,13 @@ CClient::~CClient() { th_run_ = false; sleep_.contiune(); - if (down_ && down_->file_) { - fclose(down_->file_); - down_->file_ = nullptr; + if (down_->file_.is_open()) { + down_->file_.close(); } std::lock_guard lock(mutex_); for (const auto& item : up_) { - if (item.second->file_) { - fclose(item.second->file_); - item.second->file_ = nullptr; + if (item.second->file_.is_open()) { + item.second->file_.close(); } } for (auto& item : ths_) { @@ -136,7 +134,7 @@ bool CClient::down_task(const std::string& param) } down_ = std::make_shared(); const auto& vec = task_list_[id]->files; - + if (vec.empty()) { logger_->warn("No files List, Please Check!"); return false; @@ -230,8 +228,8 @@ bool CClient::down_one_file(const std::string& id, const std::string& file, cons } logger_->warn("Start Down => {} To {}", down_->cur_remote_file_, down_->cur_file_); - down_->file_ = fopen(down_->cur_file_.c_str(), "wb"); - if (down_->file_ == nullptr) { + down_->file_.open(down_->cur_file_, std::ios::out | std::ios::binary); + if (!down_->file_.is_open()) { logger_->error("Open {} Failed.", down_->cur_file_); return false; } @@ -249,8 +247,14 @@ bool CClient::down_one_file(const std::string& id, const std::string& file, cons return false; } down_->trans_state_ = TRANS_REDAY; + cur_down_size_ = 0; + float percent = 0.0; while (down_->trans_state_ != TRANS_DONE) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + if (cur_file_size_ > 0) { + percent = (float)cur_down_size_ / cur_file_size_; + CTransProtocal::display_progress(percent); + } if (!th_run_) { logger_->error("Interrup When Receive File."); report_trans_ret(TRANS_FAILED); @@ -279,9 +283,8 @@ void CClient::report_trans_ret(TransState state, const std::string& key) return; } t->trans_state_ = state; - if (t->file_) { - fclose(t->file_); - t->file_ = nullptr; + if (t->file_.is_open()) { + t->file_.close(); if (key.empty() && t->trans_state_ == TRANS_FAILED) { fs::remove(t->cur_file_); } @@ -472,10 +475,12 @@ void CClient::handle_frame(CFrameBuffer* buf) downloading_ = true; th_down_active_ = std::thread([&]() { judget_down_active(); }); } - auto ws = fwrite(buf->data_, 1, buf->len_, down_->file_); + down_->file_.write(buf->data_, buf->len_); + auto ws = down_->file_.gcount(); if (static_cast(ws) != buf->len_) { logger_->warn("no matched write and data."); } + cur_down_size_ += ws; break; } case TYPE_OPEN_FILE: { @@ -488,9 +493,9 @@ void CClient::handle_frame(CFrameBuffer* buf) #else up_[buf->fid_]->cur_file_ = std::string(buf->data_, buf->len_); #endif - up_[buf->fid_]->file_ = fopen(up_[buf->fid_]->cur_file_.c_str(), "rb"); + 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_ == nullptr) { + if (!up_[buf->fid_]->file_.is_open()) { logger_->error("Ready Send File {} Open Failed.", up_[buf->fid_]->cur_file_); break; } @@ -564,6 +569,13 @@ void CClient::handle_frame(CFrameBuffer* buf) logger_->info("remote {} do task {} failed!", buf->fid_, list_file_); break; } + case TYPE_FILE_SIZE: { + std::string str_size(buf->data_, buf->len_); + long long size = std::stoll(str_size); + std::string show_str = OfUtil::get_file_size(size); + logger_->info("Ready Down Size:{}", show_str); + cur_file_size_ = size; + } default: break; } @@ -585,17 +597,31 @@ void CClient::send_file_data_th(const char* keys) logger_->info("Start Trans File {} To {}", t->cur_file_, str_key); std::shared_ptr buf = std::make_shared(); + buf->data_ = new char[g_BuffSize]{}; + + // seekg 用于读,seekp 用于写。 + t->file_.seekg(0, std::ios::end); + long long size = t->file_.tellg(); + t->file_.seekg(0, std::ios::beg); + buf->type_ = TYPE_FILE_SIZE; + std::string str_size = std::to_string(size); + buf->len_ = std::snprintf(buf->data_, g_BuffSize, "%s", str_size.c_str()); + if (!send_frame(buf.get())) { + report_trans_ret(TRANS_FAILED, str_key); + logger_->error("Stop Trans {} To {} failed.", t->cur_file_, str_key); + return; + } buf->type_ = TYPE_TRANS_FILE; buf->tid_ = str_key; - buf->data_ = new char[g_BuffSize]{}; buf->mark_ = 1; - while (!feof(t->file_)) { + + while (t->file_.read(buf->data_, g_BuffSize)) { if (t->trans_state_ == TRANS_BREAK) { logger_->warn("Stop Trans {} To {} failed.", t->cur_file_, str_key); report_trans_ret(TRANS_FAILED, str_key); return; } - buf->len_ = fread(buf->data_, 1, g_BuffSize, t->file_); + buf->len_ = t->file_.gcount(); if (!send_frame(buf.get())) { report_trans_ret(TRANS_FAILED, str_key); logger_->error("Stop Trans {} To {} failed.", t->cur_file_, str_key); diff --git a/client/client.h b/client/client.h index d7f4de6..959a20c 100644 --- a/client/client.h +++ b/client/client.h @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -25,7 +26,7 @@ struct TransInfomation { std::string cur_remote_id_; std::string cur_remote_file_; std::string cur_file_; - FILE* file_{}; + std::fstream file_{}; TransState trans_state_{TRANS_FAILED}; }; @@ -75,6 +76,8 @@ private: std::vector ths_; std::map> up_; std::thread th_down_active_; + long long cur_file_size_{}; + long long cur_down_size_{}; private: std::string update_list_content_; diff --git a/ofen b/ofen index 1d86de1..f690cd2 160000 --- a/ofen +++ b/ofen @@ -1 +1 @@ -Subproject commit 1d86de126afe83c7a9c934adca74006ca90ec65f +Subproject commit f690cd20e528923c6b0894b22d9f7cf40cedbcfd diff --git a/util/util.cpp b/util/util.cpp index f45194f..b697288 100644 --- a/util/util.cpp +++ b/util/util.cpp @@ -1,6 +1,7 @@ #include "util.h" #include #include +#include std::shared_ptr get_logger(const std::string& mark, const std::string& log_file) { @@ -117,6 +118,29 @@ bool CTransProtocal::pack(CFrameBuffer* buf, char** out_buf, int& len) return true; } +void CTransProtocal::display_progress(float percent) +{ + if (percent > 1.0 || percent < 0.0) { + return; + } + const int barWidth = 50; + int pos = 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() { } diff --git a/util/util.h b/util/util.h index 065f0b7..6bcc6a9 100644 --- a/util/util.h +++ b/util/util.h @@ -28,7 +28,8 @@ enum FrameType : int16_t { TYPE_UNCONFIRM_UPDATE_LIST, TYPE_DONE_UPDATE_LIST, TYPE_FAILED_UPDATE_LIST, - TYPE_GET_ID + TYPE_GET_ID, + TYPE_FILE_SIZE }; using namespace ofen; @@ -71,4 +72,5 @@ public: public: static CFrameBuffer* parse(CMutBuffer& buffer); static bool pack(CFrameBuffer* buf, char** out_buf, int& len); + static void display_progress(float percent); };