Compare commits
2 Commits
48b85abe1d
...
6a0514145d
Author | SHA1 | Date | |
---|---|---|---|
6a0514145d | |||
2989fdb7e1 |
@ -1,6 +1,6 @@
|
||||
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_REQUIRED ON)
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <iostream>
|
||||
#include <of_path.h>
|
||||
#include <of_str.h>
|
||||
#include <of_util.h>
|
||||
#include <version.h>
|
||||
|
||||
#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);
|
||||
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();
|
||||
for (const auto& cc : his) {
|
||||
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(); });
|
||||
th_down_active_ = std::thread([&]() { judget_down_active(); });
|
||||
|
||||
{
|
||||
auto* bf = new CFrameBuffer();
|
||||
bf->type_ = TYPE_GET_ID;
|
||||
send_frame(bf);
|
||||
delete bf;
|
||||
}
|
||||
|
||||
get_id();
|
||||
if (ip == "127.0.0.1") {
|
||||
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("opensource: {}", VERSION_URL);
|
||||
TLOGW("SupportCmd ==>");
|
||||
TLOGW("Get|Up|Down|Cancel|Update|Who|Where");
|
||||
TLOGW("Get|Up|Down|Cancel|Update|Who|Where|Ls|Req");
|
||||
fc_append('|');
|
||||
|
||||
while (1) {
|
||||
@ -146,6 +151,14 @@ void CClient::run(const std::string& ip, const std::string& port, const std::str
|
||||
up_task(param);
|
||||
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.");
|
||||
}
|
||||
client_->disconnect();
|
||||
@ -377,12 +390,14 @@ bool CClient::down_one_file(const std::string& id, const std::string& file, cons
|
||||
return false;
|
||||
}
|
||||
|
||||
// 在这里补充 UUID
|
||||
std::string uuid_file = uuid_ + "UUID" + file;
|
||||
// 请求下载文件
|
||||
std::shared_ptr<CFrameBuffer> buf = std::make_shared<CFrameBuffer>();
|
||||
buf->type_ = TYPE_OPEN_FILE;
|
||||
buf->tid_ = id;
|
||||
buf->data_ = new char[file.size() + 1];
|
||||
buf->len_ = std::snprintf(buf->data_, file.size() + 1, "%s", file.data());
|
||||
buf->data_ = new char[uuid_file.size() + 1];
|
||||
buf->len_ = std::snprintf(buf->data_, uuid_file.size() + 1, "%s", uuid_file.data());
|
||||
if (!send_frame(buf.get())) {
|
||||
TLOGE("{} request open file [{}] send failed.", __FUNCTION__, down_->cur_remote_file_);
|
||||
down_->cur_remote_id_.clear();
|
||||
@ -634,6 +649,96 @@ bool CClient::down_update_file(const std::map<std::string, std::string>& files)
|
||||
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)
|
||||
{
|
||||
char* out_buf{};
|
||||
@ -699,6 +804,52 @@ std::vector<std::string> CClient::load_line_his()
|
||||
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)
|
||||
{
|
||||
if (buf == nullptr) {
|
||||
@ -779,16 +930,94 @@ 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);
|
||||
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: {
|
||||
std::string keys{};
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
up_[buf->fid_] = std::make_shared<TransInfomation>();
|
||||
std::string uuid_file = std::string(buf->data_, buf->len_);
|
||||
#ifdef _WIN32
|
||||
up_[buf->fid_]->cur_file_ = CCodec::u8_to_ansi(std::string(buf->data_, buf->len_));
|
||||
#else
|
||||
up_[buf->fid_]->cur_file_ = std::string(buf->data_, buf->len_);
|
||||
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_]->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()) {
|
||||
@ -908,8 +1137,10 @@ void CClient::handle_frame(CFrameBuffer* buf)
|
||||
down_->remote_plat = static_cast<uint16_t>(std::stoul(vec[0]));
|
||||
}
|
||||
cur_file_size_ = size;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
TLOGE("UnSupport Type {}, Current Version v{}", static_cast<int>(buf->type_), VERSION_NUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ 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{};
|
||||
@ -57,11 +58,17 @@ public:
|
||||
bool request_update_list(const std::string& param);
|
||||
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 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:
|
||||
bool send_frame(CFrameBuffer* buf);
|
||||
void save_line_his(const std::string& input);
|
||||
std::vector<std::string> load_line_his();
|
||||
bool save_uuid();
|
||||
std::string read_uuid();
|
||||
void get_id();
|
||||
|
||||
private:
|
||||
void handle_frame(CFrameBuffer* buf);
|
||||
@ -96,6 +103,8 @@ private:
|
||||
std::thread update_list_th_;
|
||||
std::string own_id_{};
|
||||
std::string config_path_{};
|
||||
std::string uuid_path_{};
|
||||
std::string uuid_{};
|
||||
};
|
||||
|
||||
class CFileOpr
|
||||
|
2
ofen
2
ofen
@ -1 +1 @@
|
||||
Subproject commit a667080d96395792cd3c6066ef0ebe6c8b508bbe
|
||||
Subproject commit f6bc83b0de92adb1d5f8de7f1235c1a222c6b84b
|
@ -48,7 +48,7 @@ bool CTcpServer::start(unsigned short port)
|
||||
asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port);
|
||||
try {
|
||||
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_.listen();
|
||||
} catch (const asio::system_error& e) {
|
||||
|
@ -35,7 +35,10 @@ enum FrameType : int16_t {
|
||||
TYPE_BUSY_UPDATE_LIST,
|
||||
TYPE_FAILED_UPDATE_LIST,
|
||||
TYPE_GET_ID,
|
||||
TYPE_FILE_INFO
|
||||
TYPE_FILE_INFO,
|
||||
TYPE_GET_DIRFILES,
|
||||
TYPE_GET_DIRFILES_DONE,
|
||||
TYPE_GET_DIRFILES_FAILED,
|
||||
};
|
||||
|
||||
using namespace ofen;
|
||||
|
Loading…
x
Reference in New Issue
Block a user