change:准备将信息型数据传输改成序列化的方式,以处理更灵活的需求。
This commit is contained in:
parent
48b85abe1d
commit
2989fdb7e1
@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
project(transm VERSION 1.3.2 LANGUAGES CXX)
|
project(transm VERSION 1.4.0 LANGUAGES CXX)
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <of_path.h>
|
#include <of_path.h>
|
||||||
#include <of_str.h>
|
#include <of_str.h>
|
||||||
|
#include <of_util.h>
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
|
|
||||||
#ifdef USE_BOOST
|
#ifdef USE_BOOST
|
||||||
@ -53,6 +54,16 @@ void CClient::run(const std::string& ip, const std::string& port, const std::str
|
|||||||
{
|
{
|
||||||
fs::path fp(config_dir);
|
fs::path fp(config_dir);
|
||||||
config_path_ = fp.append("history.txt").string();
|
config_path_ = fp.append("history.txt").string();
|
||||||
|
fs::path fp2(config_dir);
|
||||||
|
uuid_path_ = fp2.append("uuid.txt").string();
|
||||||
|
|
||||||
|
save_uuid();
|
||||||
|
uuid_ = read_uuid();
|
||||||
|
if (uuid_.empty()) {
|
||||||
|
TLOGE("uuid is empty!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto his = load_line_his();
|
auto his = load_line_his();
|
||||||
for (const auto& cc : his) {
|
for (const auto& cc : his) {
|
||||||
fc_add_his(cc.c_str());
|
fc_add_his(cc.c_str());
|
||||||
@ -69,13 +80,7 @@ void CClient::run(const std::string& ip, const std::string& port, const std::str
|
|||||||
std::thread thread([&]() { io_context_.run(); });
|
std::thread thread([&]() { io_context_.run(); });
|
||||||
th_down_active_ = std::thread([&]() { judget_down_active(); });
|
th_down_active_ = std::thread([&]() { judget_down_active(); });
|
||||||
|
|
||||||
{
|
get_id();
|
||||||
auto* bf = new CFrameBuffer();
|
|
||||||
bf->type_ = TYPE_GET_ID;
|
|
||||||
send_frame(bf);
|
|
||||||
delete bf;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ip == "127.0.0.1") {
|
if (ip == "127.0.0.1") {
|
||||||
get_task_list();
|
get_task_list();
|
||||||
}
|
}
|
||||||
@ -83,7 +88,7 @@ void CClient::run(const std::string& ip, const std::string& port, const std::str
|
|||||||
TLOGI("version: {}", VERSION_NUM);
|
TLOGI("version: {}", VERSION_NUM);
|
||||||
TLOGI("opensource: {}", VERSION_URL);
|
TLOGI("opensource: {}", VERSION_URL);
|
||||||
TLOGW("SupportCmd ==>");
|
TLOGW("SupportCmd ==>");
|
||||||
TLOGW("Get|Up|Down|Cancel|Update|Who|Where");
|
TLOGW("Get|Up|Down|Cancel|Update|Who|Where|Ls|Req");
|
||||||
fc_append('|');
|
fc_append('|');
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -146,6 +151,14 @@ void CClient::run(const std::string& ip, const std::string& port, const std::str
|
|||||||
up_task(param);
|
up_task(param);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (scmd == "Ls" || scmd == "ls") {
|
||||||
|
require_dir_files(param);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (scmd == "Req" || scmd == "req") {
|
||||||
|
down_req_list(param);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
TLOGE("No matched cmd, May be param size incorrect.");
|
TLOGE("No matched cmd, May be param size incorrect.");
|
||||||
}
|
}
|
||||||
client_->disconnect();
|
client_->disconnect();
|
||||||
@ -377,12 +390,14 @@ bool CClient::down_one_file(const std::string& id, const std::string& file, cons
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 在这里补充 UUID
|
||||||
|
std::string uuid_file = uuid_ + "UUID" + file;
|
||||||
// 请求下载文件
|
// 请求下载文件
|
||||||
std::shared_ptr<CFrameBuffer> buf = std::make_shared<CFrameBuffer>();
|
std::shared_ptr<CFrameBuffer> buf = std::make_shared<CFrameBuffer>();
|
||||||
buf->type_ = TYPE_OPEN_FILE;
|
buf->type_ = TYPE_OPEN_FILE;
|
||||||
buf->tid_ = id;
|
buf->tid_ = id;
|
||||||
buf->data_ = new char[file.size() + 1];
|
buf->data_ = new char[uuid_file.size() + 1];
|
||||||
buf->len_ = std::snprintf(buf->data_, file.size() + 1, "%s", file.data());
|
buf->len_ = std::snprintf(buf->data_, uuid_file.size() + 1, "%s", uuid_file.data());
|
||||||
if (!send_frame(buf.get())) {
|
if (!send_frame(buf.get())) {
|
||||||
TLOGE("{} request open file [{}] send failed.", __FUNCTION__, down_->cur_remote_file_);
|
TLOGE("{} request open file [{}] send failed.", __FUNCTION__, down_->cur_remote_file_);
|
||||||
down_->cur_remote_id_.clear();
|
down_->cur_remote_id_.clear();
|
||||||
@ -634,6 +649,96 @@ bool CClient::down_update_file(const std::map<std::string, std::string>& files)
|
|||||||
return suc;
|
return suc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CClient::get_dir_files(const std::string& dir, std::string& out, std::string& error)
|
||||||
|
{
|
||||||
|
fs::path p(dir);
|
||||||
|
out.clear();
|
||||||
|
error.clear();
|
||||||
|
if (!fs::is_directory(p) || !fs::exists(p)) {
|
||||||
|
error = fmt::format("{} not a dir or not exist", p.string());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// F开头文件,D开头目录,使用前需要去除。
|
||||||
|
for (const auto& entry : fs::directory_iterator(p)) {
|
||||||
|
if (fs::is_directory(entry)) {
|
||||||
|
out += "D" + COfPath::standardize(entry.path().string()) + "\n";
|
||||||
|
} else {
|
||||||
|
out += "F" + COfPath::standardize(entry.path().string()) + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CClient::require_dir_files(const std::string& param)
|
||||||
|
{
|
||||||
|
auto tvec = COfStr::split(param, " ");
|
||||||
|
if (tvec.size() < 2) {
|
||||||
|
TLOGE("{} invalid param format [{}]", __FUNCTION__, param);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int index = std::stoi(tvec[0]);
|
||||||
|
std::string path = tvec[1];
|
||||||
|
|
||||||
|
if (!task_list_.count(index)) {
|
||||||
|
TLOGE("No Index Found {}.", index);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& sr = task_list_[index];
|
||||||
|
std::shared_ptr<CFrameBuffer> buf = std::make_shared<CFrameBuffer>();
|
||||||
|
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());
|
||||||
|
buf->tid_ = sr->id;
|
||||||
|
|
||||||
|
if (!send_frame(buf.get())) {
|
||||||
|
TLOGE("Send Failed {}", __LINE__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CClient::down_req_list(const std::string& param)
|
||||||
|
{
|
||||||
|
auto tvec = COfStr::split(param, " ");
|
||||||
|
if (tvec.size() < 2) {
|
||||||
|
TLOGE("{} invalid param format [{}]", __FUNCTION__, param);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int index = std::stoi(tvec[0]);
|
||||||
|
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);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& sr = task_list_[index];
|
||||||
|
if (sr->id == own_id_) {
|
||||||
|
TLOGE("Can't Req Self Task {}.", sr->id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
down_ = std::make_shared<TransInfomation>();
|
||||||
|
auto vec = COfStr::split(lists, "|");
|
||||||
|
for (const auto& item : vec) {
|
||||||
|
auto path = COfStr::trim(item);
|
||||||
|
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)) {
|
||||||
|
TLOGE("Down Failed {}", __LINE__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CClient::send_frame(CFrameBuffer* buf)
|
bool CClient::send_frame(CFrameBuffer* buf)
|
||||||
{
|
{
|
||||||
char* out_buf{};
|
char* out_buf{};
|
||||||
@ -699,6 +804,52 @@ std::vector<std::string> CClient::load_line_his()
|
|||||||
return history;
|
return history;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CClient::save_uuid()
|
||||||
|
{
|
||||||
|
fs::path uuid_path(uuid_path_);
|
||||||
|
if (fs::exists(uuid_path)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::ofstream out_file(uuid_path.string(), std::ios::out);
|
||||||
|
if (!out_file.is_open()) {
|
||||||
|
TLOGE("Open File Failed {}", uuid_path.string());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string uuid1 = OfUtil::get_uuid();
|
||||||
|
std::string uuid2 = OfUtil::get_uuid();
|
||||||
|
std::string uuid = uuid1 + "-" + uuid2;
|
||||||
|
out_file << uuid;
|
||||||
|
out_file.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CClient::read_uuid()
|
||||||
|
{
|
||||||
|
fs::path uuid_path(uuid_path_);
|
||||||
|
if (!fs::exists(uuid_path)) {
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
std::ifstream in_file(uuid_path.string(), std::ios::in);
|
||||||
|
if (!in_file.is_open()) {
|
||||||
|
TLOGE("Open File Failed {}", uuid_path.string());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string uuid;
|
||||||
|
in_file >> uuid;
|
||||||
|
in_file.close();
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
send_frame(bf);
|
||||||
|
delete bf;
|
||||||
|
}
|
||||||
|
|
||||||
void CClient::handle_frame(CFrameBuffer* buf)
|
void CClient::handle_frame(CFrameBuffer* buf)
|
||||||
{
|
{
|
||||||
if (buf == nullptr) {
|
if (buf == nullptr) {
|
||||||
@ -779,16 +930,94 @@ void CClient::handle_frame(CFrameBuffer* buf)
|
|||||||
}
|
}
|
||||||
break;
|
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);
|
||||||
|
std::string err;
|
||||||
|
std::string out;
|
||||||
|
if (!get_dir_files(path, 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());
|
||||||
|
} 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());
|
||||||
|
}
|
||||||
|
std::swap(buf->tid_, buf->fid_);
|
||||||
|
if (!send_frame(buf)) {
|
||||||
|
TLOGE("Send Failed {}.", __LINE__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TYPE_GET_DIRFILES_FAILED: {
|
||||||
|
std::string err(buf->data_, buf->len_);
|
||||||
|
TLOGE("Get {} Dir Files Failed. {}", buf->fid_, err);
|
||||||
|
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");
|
||||||
|
TLOGD("$$$$$$$$$ START $$$$$$$$$");
|
||||||
|
for (const auto& item : vec) {
|
||||||
|
std::string real = COfStr::trim(item);
|
||||||
|
if (real.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (real.find("D") == 0) {
|
||||||
|
real.erase(0, 1);
|
||||||
|
TLOGI("d=>{}", real);
|
||||||
|
} else if (real.find("F") == 0) {
|
||||||
|
real.erase(0, 1);
|
||||||
|
TLOGI("f=>{}", real);
|
||||||
|
} else {
|
||||||
|
TLOGE("Error Remote List Format {}", real);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TLOGD("$$$$$$$$$ OVER $$$$$$$$$");
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TYPE_OPEN_FILE: {
|
case TYPE_OPEN_FILE: {
|
||||||
std::string keys{};
|
std::string keys{};
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
up_[buf->fid_] = std::make_shared<TransInfomation>();
|
up_[buf->fid_] = std::make_shared<TransInfomation>();
|
||||||
|
std::string uuid_file = std::string(buf->data_, buf->len_);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
up_[buf->fid_]->cur_file_ = CCodec::u8_to_ansi(std::string(buf->data_, buf->len_));
|
uuid_file = CCodec::u8_to_ansi(uuid_file);
|
||||||
#else
|
|
||||||
up_[buf->fid_]->cur_file_ = std::string(buf->data_, buf->len_);
|
|
||||||
#endif
|
#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_]->file_.open(up_[buf->fid_]->cur_file_, std::ios::in | std::ios::binary);
|
up_[buf->fid_]->file_.open(up_[buf->fid_]->cur_file_, std::ios::in | std::ios::binary);
|
||||||
up_[buf->fid_]->trans_state_ = TRANS_REDAY;
|
up_[buf->fid_]->trans_state_ = TRANS_REDAY;
|
||||||
if (!up_[buf->fid_]->file_.is_open()) {
|
if (!up_[buf->fid_]->file_.is_open()) {
|
||||||
@ -908,8 +1137,10 @@ void CClient::handle_frame(CFrameBuffer* buf)
|
|||||||
down_->remote_plat = static_cast<uint16_t>(std::stoul(vec[0]));
|
down_->remote_plat = static_cast<uint16_t>(std::stoul(vec[0]));
|
||||||
}
|
}
|
||||||
cur_file_size_ = size;
|
cur_file_size_ = size;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
TLOGE("UnSupport Type {}, Current Version v{}", static_cast<int>(buf->type_), VERSION_NUM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ enum TransState {
|
|||||||
struct TransInfomation {
|
struct TransInfomation {
|
||||||
std::string cur_remote_id_;
|
std::string cur_remote_id_;
|
||||||
std::string cur_remote_file_;
|
std::string cur_remote_file_;
|
||||||
|
std::string cur_remote_uuid_;
|
||||||
std::string cur_file_;
|
std::string cur_file_;
|
||||||
std::fstream file_{};
|
std::fstream file_{};
|
||||||
uint16_t permissions{};
|
uint16_t permissions{};
|
||||||
@ -57,11 +58,17 @@ public:
|
|||||||
bool request_update_list(const std::string& param);
|
bool request_update_list(const std::string& param);
|
||||||
bool check_update_list(const std::string& content, std::map<std::string, std::string>& files);
|
bool check_update_list(const std::string& content, std::map<std::string, std::string>& files);
|
||||||
bool down_update_file(const std::map<std::string, std::string>& files);
|
bool down_update_file(const std::map<std::string, std::string>& files);
|
||||||
|
bool get_dir_files(const std::string& dir, std::string& out, std::string& error);
|
||||||
|
bool require_dir_files(const std::string& param);
|
||||||
|
bool down_req_list(const std::string& param);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool send_frame(CFrameBuffer* buf);
|
bool send_frame(CFrameBuffer* buf);
|
||||||
void save_line_his(const std::string& input);
|
void save_line_his(const std::string& input);
|
||||||
std::vector<std::string> load_line_his();
|
std::vector<std::string> load_line_his();
|
||||||
|
bool save_uuid();
|
||||||
|
std::string read_uuid();
|
||||||
|
void get_id();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handle_frame(CFrameBuffer* buf);
|
void handle_frame(CFrameBuffer* buf);
|
||||||
@ -96,6 +103,8 @@ private:
|
|||||||
std::thread update_list_th_;
|
std::thread update_list_th_;
|
||||||
std::string own_id_{};
|
std::string own_id_{};
|
||||||
std::string config_path_{};
|
std::string config_path_{};
|
||||||
|
std::string uuid_path_{};
|
||||||
|
std::string uuid_{};
|
||||||
};
|
};
|
||||||
|
|
||||||
class CFileOpr
|
class CFileOpr
|
||||||
|
@ -48,7 +48,7 @@ bool CTcpServer::start(unsigned short port)
|
|||||||
asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port);
|
asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port);
|
||||||
try {
|
try {
|
||||||
acceptor_.open(endpoint.protocol());
|
acceptor_.open(endpoint.protocol());
|
||||||
//acceptor_.set_option(asio::socket_base::reuse_address(true));
|
// acceptor_.set_option(asio::socket_base::reuse_address(true));
|
||||||
acceptor_.bind(endpoint);
|
acceptor_.bind(endpoint);
|
||||||
acceptor_.listen();
|
acceptor_.listen();
|
||||||
} catch (const asio::system_error& e) {
|
} catch (const asio::system_error& e) {
|
||||||
|
@ -35,7 +35,10 @@ enum FrameType : int16_t {
|
|||||||
TYPE_BUSY_UPDATE_LIST,
|
TYPE_BUSY_UPDATE_LIST,
|
||||||
TYPE_FAILED_UPDATE_LIST,
|
TYPE_FAILED_UPDATE_LIST,
|
||||||
TYPE_GET_ID,
|
TYPE_GET_ID,
|
||||||
TYPE_FILE_INFO
|
TYPE_FILE_INFO,
|
||||||
|
TYPE_GET_DIRFILES,
|
||||||
|
TYPE_GET_DIRFILES_DONE,
|
||||||
|
TYPE_GET_DIRFILES_FAILED,
|
||||||
};
|
};
|
||||||
|
|
||||||
using namespace ofen;
|
using namespace ofen;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user