NasBackup

设计方案

由五个主要类组成

1
2
3
4
5
SmbContextManager
SmbSession
SmbDirectory
SmbFileTransfer
SmbTaskExecutor

主要类设计

SmbContextManager — 全局上下文与连接管理

职能

  • 初始化/销毁 libsmb2 上下文 (smb2_context)
  • 管理连接(IP、端口、身份认证)
  • 提供连接状态查询

核心点

  • 封装 smb2_init_context、smb2_connect_share、smb2_destroy_context
  • 保证线程安全(多个 task 调用)

SmbSession — 与具体远程共享的会话

职能

  • 表示一次 NAS 登录会话(绑定一个 SmbContextManager)
  • 负责目录与文件的逻辑操作:浏览、创建、删除
  • 是上层与传输、任务的桥梁

SmbDirectory — 目录操作对象

职能

  • 封装目录的抽象操作
  • 主要用于更清晰地组织 List/Mkdir
  • 方便 UI 层实现目录树、文件浏览

SmbFileTransfer — 上传/下载的异步任务控制器(核心类)

职能

  • 封装文件上传 / 下载逻辑
  • 支持异步执行(后台线程)
  • 支持进度回调、错误回调、取消

关键逻辑

  • 封装 libsmb2 的 smb2_open / smb2_write / smb2_read
  • 利用线程或线程池执行

SmbTaskExecutor — 通用任务调度器

职能

  • 提供异步任务队列
  • 类似一个简单线程池
  • SmbFileTransfer 可以通过它执行任务

类关系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
+-------------------+
| SmbContextManager |
+-------------------+
|
v
+-------------------+
| SmbSession |----> SmbDirectory
| (Context wrapper) |
+-------------------+
|
v
+-------------------+
| SmbFileTransfer |
+-------------------+
|
v
+-------------------+
| SmbTaskExecutor |
+-------------------+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class SmbContextManager {
public:
SmbContextManager();
~SmbContextManager();

bool Connect(const DeviceInfo& deviceInfo);
void Disconnect();
bool IsConnected() const;

struct smb2_context* GetContext();
std::string GetSharePath() const;

private:
std::unique_ptr<smb2_context, decltype(&smb2_destroy_context)> ctx_;
mutable std::mutex mutex_;
bool connected_ = false;
DeviceInfo deviceInfo_;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include "smb/smb_context_manager.h"
#include "smb2/smb2.h"

SmbContextManager::SmbContextManager() : ctx_(nullptr, smb2_destroy_context) {}

SmbContextManager::~SmbContextManager() { Disconnect(); }

bool SmbContextManager::Connect(const DeviceInfo &deviceInfo) {
std::lock_guard<std::mutex> lock(mutex_);
deviceInfo_ = deviceInfo;
// 初始化 context
ctx_.reset(smb2_init_context());
if (!ctx_) {
return false;
}

smb2_set_security_mode(ctx_.get(), SMB2_NEGOTIATE_SIGNING_REQUIRED);

smb2_set_user(ctx_.get(), deviceInfo_.user_.c_str());
smb2_set_password(ctx_.get(), deviceInfo_.password_.c_str());

if (smb2_connect_share(ctx_.get(), deviceInfo_.server_.c_str(), "IPC$",
deviceInfo_.user_.c_str()) != 0) {
ctx_.reset();
return false;
}
connected_ = true;
return true;
}

void SmbContextManager::Disconnect() {
std::lock_guard<std::mutex> lock(mutex_);
if (ctx_) {
smb2_disconnect_share(ctx_.get());
ctx_.reset();
}
connected_ = false;
}

bool SmbContextManager::IsConnected() const {
std::lock_guard<std::mutex> lock(mutex_);
return connected_;
}

struct smb2_context *SmbContextManager::GetContext() {
std::lock_guard<std::mutex> lock(mutex_);
return ctx_.get();
}

std::string SmbContextManager::GetSharePath() const { return deviceInfo_.share_; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "smb/smb_context_manager.h"

class SmbFileTransfer;
class SmbDirectory;

class SmbSession {
explicit SmbSession(std::shared_ptr<SmbContextManager> context);
~SmbSession() = default;

std::vector<std::string> ListDirectory(const std::string &remotePath);
bool CreateDirectory(const std::string &remotePath);

std::shared_ptr<SmbFileTransfer> CreateTransfer();

private:
std::shared_ptr<SmbContextManager> ctx_manager_;
};