备份-基础ssl通信
This commit is contained in:
471
Client-Native/架构设计.md
Normal file
471
Client-Native/架构设计.md
Normal file
@@ -0,0 +1,471 @@
|
||||
# Client-Native 架构设计文档
|
||||
|
||||
## 🏗️ 类图 (Class Diagram)
|
||||
|
||||
```
|
||||
┌─────────────────────────────┐
|
||||
│ <<static class>> │
|
||||
│ CertificateConfig │
|
||||
├─────────────────────────────┤
|
||||
│ + GetClientCertificate() │
|
||||
│ + GetClientPrivateKey() │
|
||||
│ + GetCACertificate() │
|
||||
│ + GetKeyPassword() │
|
||||
└─────────────────────────────┘
|
||||
△
|
||||
│ uses
|
||||
│
|
||||
┌─────────────────────────────┐ ┌─────────────────────────────┐
|
||||
│ CertificateManager │ │ SSLClientConnection │
|
||||
├─────────────────────────────┤ ├─────────────────────────────┤
|
||||
│ - (no state) │ │ - m_sslContext: SSL_CTX* │
|
||||
├─────────────────────────────┤ │ - m_ssl: SSL* │
|
||||
│ + LoadCertificateFromMemory()│◄───────┤ - m_socket: SOCKET │
|
||||
│ + LoadPrivateKeyFromMemory()│ uses │ - m_isConnected: bool │
|
||||
│ + PrintSSLError() │ │ - m_certManager: CertMgr │
|
||||
└─────────────────────────────┘ ├─────────────────────────────┤
|
||||
△ │ + Initialize() │
|
||||
│ uses │ + Connect() │
|
||||
│ │ + Send() │
|
||||
│ │ + Receive() │
|
||||
│ │ + Disconnect() │
|
||||
┌─────────────────────────────┐ │ + IsConnected() │
|
||||
│ main() │ │ + GetCipherSuite() │
|
||||
│ │ ├─────────────────────────────┤
|
||||
│ [Application Entry Point] │───────>│ - InitializeWinsock() │
|
||||
│ │ uses │ - Cleanup() │
|
||||
└─────────────────────────────┘ └─────────────────────────────┘
|
||||
```
|
||||
|
||||
## 📊 模块关系图
|
||||
|
||||
```
|
||||
main.cpp
|
||||
│
|
||||
├──► SSLClientConnection (主要依赖)
|
||||
│ │
|
||||
│ ├──► CertificateManager (内部依赖)
|
||||
│ │ │
|
||||
│ │ └──► OpenSSL API
|
||||
│ │
|
||||
│ └──► Winsock2 API
|
||||
│
|
||||
└──► CertificateConfig (直接依赖)
|
||||
```
|
||||
|
||||
## 🔄 对象生命周期
|
||||
|
||||
```
|
||||
┌────── main() starts ──────┐
|
||||
│ │
|
||||
│ ┌──────────────────────┐ │
|
||||
│ │ SSLClientConnection │ │ <── 创建对象(栈上)
|
||||
│ │ │ │
|
||||
│ │ ┌────────────────┐ │ │
|
||||
│ │ │ CertManager │ │ │ <── 自动创建成员对象
|
||||
│ │ └────────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ [Initialize] │ │ <── 分配SSL资源
|
||||
│ │ └─> SSL_CTX* │ │
|
||||
│ │ └─> 加载证书 │ │
|
||||
│ │ │ │
|
||||
│ │ [Connect] │ │ <── 分配Socket/SSL
|
||||
│ │ └─> SOCKET │ │
|
||||
│ │ └─> SSL* │ │
|
||||
│ │ └─> SSL握手 │ │
|
||||
│ │ │ │
|
||||
│ │ [Send/Receive] │ │ <── 数据传输
|
||||
│ │ └─> SSL_write() │ │
|
||||
│ │ └─> SSL_read() │ │
|
||||
│ │ │ │
|
||||
│ │ [~Destructor] │ │ <── 自动清理
|
||||
│ │ └─> SSL_free() │ │
|
||||
│ │ └─> closesocket()│ │
|
||||
│ │ └─> SSL_CTX_free│ │
|
||||
│ └──────────────────────┘ │
|
||||
│ │
|
||||
└────── main() ends ────────┘
|
||||
(自动析构,无需手动清理)
|
||||
```
|
||||
|
||||
## 🎯 设计模式应用
|
||||
|
||||
### 1. RAII (Resource Acquisition Is Initialization)
|
||||
|
||||
```cpp
|
||||
class SSLClientConnection {
|
||||
public:
|
||||
SSLClientConnection() // 构造函数 - 初始化状态
|
||||
: m_sslContext(nullptr)
|
||||
, m_ssl(nullptr)
|
||||
, m_socket(INVALID_SOCKET)
|
||||
, m_isConnected(false)
|
||||
{}
|
||||
|
||||
~SSLClientConnection() // 析构函数 - 自动清理资源
|
||||
{
|
||||
Cleanup(); // 释放SSL、Socket等资源
|
||||
}
|
||||
|
||||
// 禁止拷贝(避免资源重复释放)
|
||||
SSLClientConnection(const SSLClientConnection&) = delete;
|
||||
SSLClientConnection& operator=(const SSLClientConnection&) = delete;
|
||||
};
|
||||
|
||||
使用:
|
||||
{
|
||||
SSLClientConnection client; // 自动调用构造函数
|
||||
client.Initialize(...);
|
||||
client.Connect(...);
|
||||
// ...
|
||||
} // ← 离开作用域,自动调用析构函数清理
|
||||
```
|
||||
|
||||
### 2. Static Factory (静态工厂)
|
||||
|
||||
```cpp
|
||||
class CertificateConfig {
|
||||
public:
|
||||
// 静态方法,无需实例化
|
||||
static const char* GetClientCertificate() {
|
||||
return g_clientCert;
|
||||
}
|
||||
|
||||
private:
|
||||
// 私有构造函数,防止实例化
|
||||
CertificateConfig() = default;
|
||||
~CertificateConfig() = default;
|
||||
};
|
||||
|
||||
使用:
|
||||
const char* cert = CertificateConfig::GetClientCertificate(); // 直接调用
|
||||
```
|
||||
|
||||
### 3. Manager Pattern (管理器模式)
|
||||
|
||||
```cpp
|
||||
class CertificateManager {
|
||||
public:
|
||||
// 无状态的工具方法
|
||||
X509* LoadCertificateFromMemory(const char* certPem);
|
||||
EVP_PKEY* LoadPrivateKeyFromMemory(const char* keyPem, ...);
|
||||
static void PrintSSLError(const char* message);
|
||||
};
|
||||
|
||||
使用:
|
||||
CertificateManager mgr;
|
||||
X509* cert = mgr.LoadCertificateFromMemory(certData);
|
||||
```
|
||||
|
||||
### 4. Facade Pattern (外观模式)
|
||||
|
||||
```cpp
|
||||
// SSLClientConnection 提供简化的接口
|
||||
// 隐藏底层 OpenSSL + Winsock 的复杂性
|
||||
|
||||
class SSLClientConnection {
|
||||
public:
|
||||
// 简单易用的接口
|
||||
bool Initialize(...); // 内部处理 SSL_CTX、证书加载等
|
||||
bool Connect(...); // 内部处理 socket、SSL握手等
|
||||
bool Send(...); // 内部处理 SSL_write
|
||||
int Receive(...); // 内部处理 SSL_read
|
||||
|
||||
private:
|
||||
// 隐藏复杂的内部实现
|
||||
bool InitializeWinsock();
|
||||
void Cleanup();
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
## 📐 架构层次
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 应用层 (Application Layer) │ ← main.cpp
|
||||
│ - 用户交互 │
|
||||
│ - 命令处理 │
|
||||
│ - 主循环控制 │
|
||||
└─────────────────────────────────────────┘
|
||||
↓ uses
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 业务层 (Business Layer) │ ← SSLClientConnection
|
||||
│ - SSL连接管理 │
|
||||
│ - 数据发送/接收 │
|
||||
│ - 连接状态管理 │
|
||||
└─────────────────────────────────────────┘
|
||||
↓ uses
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 工具层 (Utility Layer) │ ← CertificateManager
|
||||
│ - 证书加载 │
|
||||
│ - 错误处理 │
|
||||
│ - 通用工具 │
|
||||
└─────────────────────────────────────────┘
|
||||
↓ uses
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 数据层 (Data Layer) │ ← CertificateConfig
|
||||
│ - 证书数据 │
|
||||
│ - 配置数据 │
|
||||
└─────────────────────────────────────────┘
|
||||
↓ uses
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 系统层 (System Layer) │
|
||||
│ - OpenSSL API │
|
||||
│ - Winsock2 API │
|
||||
│ - Windows API │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 🔐 数据流图
|
||||
|
||||
### 初始化流程
|
||||
```
|
||||
main()
|
||||
│
|
||||
├─> CertificateConfig::GetClientCertificate()
|
||||
│ │
|
||||
│ └─> return g_clientCert
|
||||
│
|
||||
├─> SSLClientConnection::Initialize(cert, key, ca, pwd)
|
||||
│ │
|
||||
│ ├─> SSL_CTX_new(TLS_client_method())
|
||||
│ │
|
||||
│ ├─> CertificateManager::LoadCertificateFromMemory(ca)
|
||||
│ │ │
|
||||
│ │ ├─> BIO_new_mem_buf()
|
||||
│ │ ├─> PEM_read_bio_X509()
|
||||
│ │ └─> return X509*
|
||||
│ │
|
||||
│ ├─> SSL_CTX_use_certificate()
|
||||
│ │
|
||||
│ └─> SSL_CTX_use_PrivateKey()
|
||||
│
|
||||
└─> SSLClientConnection::Connect(address, port)
|
||||
│
|
||||
├─> socket() → SOCKET
|
||||
├─> connect() → TCP连接
|
||||
├─> SSL_new() → SSL*
|
||||
├─> SSL_set_fd()
|
||||
└─> SSL_connect() → SSL握手
|
||||
```
|
||||
|
||||
### 数据传输流程
|
||||
```
|
||||
main() [用户输入 "1"]
|
||||
│
|
||||
├─> SSLClientConnection::Send("hello")
|
||||
│ │
|
||||
│ └─> SSL_write(m_ssl, "hello", 5)
|
||||
│ │
|
||||
│ └─> [加密] → 网络发送
|
||||
│
|
||||
└─> SSLClientConnection::Receive(buffer, size)
|
||||
│
|
||||
└─> SSL_read(m_ssl, buffer, size)
|
||||
│
|
||||
└─> 网络接收 → [解密] → buffer
|
||||
```
|
||||
|
||||
## 💾 内存布局
|
||||
|
||||
```
|
||||
Stack (栈):
|
||||
┌──────────────────────────────────────┐
|
||||
│ main() 函数帧 │
|
||||
│ ├─ SSLClientConnection client; │ <── 完整对象
|
||||
│ │ ├─ m_sslContext: SSL_CTX* │ <── 指针(8字节)
|
||||
│ │ ├─ m_ssl: SSL* │ <── 指针(8字节)
|
||||
│ │ ├─ m_socket: SOCKET │ <── 句柄(8字节)
|
||||
│ │ ├─ m_isConnected: bool │ <── 布尔(1字节)
|
||||
│ │ └─ m_certManager: CertMgr │ <── 空对象(1字节)
|
||||
│ │ │
|
||||
│ └─ char receiveBuffer[1024]; │ <── 缓冲区
|
||||
└──────────────────────────────────────┘
|
||||
|
||||
Heap (堆):
|
||||
┌──────────────────────────────────────┐
|
||||
│ SSL_CTX 结构体 ←─ m_sslContext │
|
||||
│ SSL 结构体 ←─ m_ssl │
|
||||
│ X509 证书对象 │
|
||||
│ EVP_PKEY 私钥对象 │
|
||||
│ ... │
|
||||
└──────────────────────────────────────┘
|
||||
|
||||
析构时自动释放所有堆内存
|
||||
```
|
||||
|
||||
## 📊 编译依赖关系
|
||||
|
||||
```
|
||||
main.cpp
|
||||
├─ #include "pch.h"
|
||||
├─ #include "CertificateConfig.h"
|
||||
└─ #include "SSLClientConnection.h"
|
||||
|
||||
SSLClientConnection.cpp
|
||||
├─ #include "pch.h"
|
||||
├─ #include "SSLClientConnection.h"
|
||||
└─ #include "CertificateManager.h"
|
||||
|
||||
CertificateManager.cpp
|
||||
├─ #include "pch.h"
|
||||
└─ #include "CertificateManager.h"
|
||||
|
||||
CertificateConfig.cpp
|
||||
├─ #include "pch.h"
|
||||
└─ #include "CertificateConfig.h"
|
||||
|
||||
pch.h (预编译头)
|
||||
├─ #include <winsock2.h>
|
||||
├─ #include <windows.h>
|
||||
├─ #include <openssl/ssl.h>
|
||||
├─ #include <openssl/err.h>
|
||||
└─ ... (其他系统头文件)
|
||||
```
|
||||
|
||||
## 🧪 单元测试架构(未来扩展)
|
||||
|
||||
```cpp
|
||||
// 伪代码示例
|
||||
|
||||
TEST_SUITE(CertificateConfigTest) {
|
||||
TEST(GetClientCertificate_ReturnsValidCert) {
|
||||
const char* cert = CertificateConfig::GetClientCertificate();
|
||||
ASSERT_NOT_NULL(cert);
|
||||
ASSERT_TRUE(strstr(cert, "BEGIN CERTIFICATE"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_SUITE(CertificateManagerTest) {
|
||||
TEST(LoadCertificateFromMemory_ValidCert_ReturnsX509) {
|
||||
CertificateManager mgr;
|
||||
X509* cert = mgr.LoadCertificateFromMemory(validCert);
|
||||
ASSERT_NOT_NULL(cert);
|
||||
X509_free(cert);
|
||||
}
|
||||
|
||||
TEST(LoadCertificateFromMemory_InvalidCert_ReturnsNull) {
|
||||
CertificateManager mgr;
|
||||
X509* cert = mgr.LoadCertificateFromMemory("invalid");
|
||||
ASSERT_NULL(cert);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_SUITE(SSLClientConnectionTest) {
|
||||
TEST(Initialize_ValidCerts_ReturnsTrue) {
|
||||
SSLClientConnection client;
|
||||
bool result = client.Initialize(
|
||||
validCert, validKey, validCA, "password"
|
||||
);
|
||||
ASSERT_TRUE(result);
|
||||
}
|
||||
|
||||
TEST(Connect_InvalidAddress_ReturnsFalse) {
|
||||
SSLClientConnection client;
|
||||
client.Initialize(...);
|
||||
bool result = client.Connect("0.0.0.0", 99999);
|
||||
ASSERT_FALSE(result);
|
||||
}
|
||||
|
||||
TEST(Send_NotConnected_ReturnsFalse) {
|
||||
SSLClientConnection client;
|
||||
bool result = client.Send("hello");
|
||||
ASSERT_FALSE(result);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 配置和扩展点
|
||||
|
||||
### 扩展点 1: 支持配置文件
|
||||
```cpp
|
||||
// 未来可以添加
|
||||
class ConfigReader {
|
||||
public:
|
||||
ServerConfig ReadFromFile(const std::string& path);
|
||||
};
|
||||
|
||||
// 使用
|
||||
ConfigReader reader;
|
||||
ServerConfig config = reader.ReadFromFile("config.json");
|
||||
client.Connect(config.address, config.port);
|
||||
```
|
||||
|
||||
### 扩展点 2: 日志系统
|
||||
```cpp
|
||||
// 未来可以添加
|
||||
class Logger {
|
||||
public:
|
||||
static void Info(const std::string& msg);
|
||||
static void Error(const std::string& msg);
|
||||
static void Debug(const std::string& msg);
|
||||
};
|
||||
|
||||
// 在SSLClientConnection中使用
|
||||
Logger::Info("SSL握手成功");
|
||||
Logger::Error("连接失败");
|
||||
```
|
||||
|
||||
### 扩展点 3: 异步IO
|
||||
```cpp
|
||||
// 未来可以添加
|
||||
class AsyncSSLClient : public SSLClientConnection {
|
||||
public:
|
||||
std::future<bool> ConnectAsync(const char* addr, int port);
|
||||
std::future<bool> SendAsync(const std::string& data);
|
||||
std::future<int> ReceiveAsync(char* buffer, int size);
|
||||
};
|
||||
```
|
||||
|
||||
## 📈 性能考虑
|
||||
|
||||
| 方面 | 原版 | 重构版 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| **函数调用开销** | 直接调用 | 通过对象调用 | 编译器内联优化,无差异 |
|
||||
| **内存使用** | 全局变量 | 栈上对象 | 相同(对象很小) |
|
||||
| **缓存友好性** | 中等 | 好 | 相关数据集中在对象内 |
|
||||
| **编译优化** | 好 | 好 | 现代编译器优化效果相同 |
|
||||
|
||||
**结论**: 重构对运行时性能几乎无影响。
|
||||
|
||||
## 📚 代码度量
|
||||
|
||||
```
|
||||
复杂度 (Cyclomatic Complexity):
|
||||
- 原版 main(): ~25 (高复杂度)
|
||||
- 重构版 main(): ~8 (低复杂度)
|
||||
- SSLClientConnection::Connect(): ~12 (中等复杂度)
|
||||
- CertificateManager::Load*(): ~5 (低复杂度)
|
||||
|
||||
耦合度 (Coupling):
|
||||
- 原版: 高耦合(全局变量)
|
||||
- 重构版: 低耦合(依赖注入)
|
||||
|
||||
内聚度 (Cohesion):
|
||||
- 原版: 低内聚(功能分散)
|
||||
- 重构版: 高内聚(功能集中)
|
||||
```
|
||||
|
||||
## 🎓 学习建议
|
||||
|
||||
### 初学者
|
||||
1. 先理解原版 `main.cpp.backup`
|
||||
2. 运行并测试原版代码
|
||||
3. 阅读重构版各模块
|
||||
4. 对比理解设计改进
|
||||
|
||||
### 中级开发者
|
||||
1. 分析类的职责划分
|
||||
2. 理解RAII资源管理
|
||||
3. 学习设计模式应用
|
||||
4. 尝试添加单元测试
|
||||
|
||||
### 高级开发者
|
||||
1. 评估架构设计
|
||||
2. 考虑性能优化
|
||||
3. 扩展功能(如异步IO)
|
||||
4. 改进错误处理
|
||||
|
||||
---
|
||||
**总结**: 这个重构展示了从"过程式编程"到"面向对象编程"的完整转变,是学习现代C++工程实践的绝佳案例。
|
||||
Reference in New Issue
Block a user