Files
2026-01-23 08:39:07 +08:00
..
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00
2026-01-23 08:39:07 +08:00

Client-Native 说明文档

项目简介

Client-Native 是一个纯OpenSSL+Winsock实现的SSL客户端不使用HP-Socket库

这个项目的目的是:

  1. 展示底层SSL通信的实现细节
  2. 对比HP-Socket封装的便利性
  3. 帮助理解SSL/TLS协议的工作原理

功能对比

Client使用HP-Socket

// 简单的几行代码就能实现SSL客户端
CClientListener listener;
CSSLClientPtr client(&listener);

// 初始化SSLHP-Socket封装
client->SetupSSLContextByMemory(...);

// 连接服务器HP-Socket封装
client->Start(address, port);

// 发送数据HP-Socket封装
client->Send(data, length);

Client-Native纯OpenSSL+Winsock

// 需要手动处理很多底层细节

// 1. 初始化Winsock
WSAStartup(...);

// 2. 创建socket
socket = socket(AF_INET, SOCK_STREAM, ...);

// 3. 连接服务器
connect(socket, ...);

// 4. 创建SSL上下文
SSL_CTX* ctx = SSL_CTX_new(TLS_client_method());

// 5. 加载证书和私钥
SSL_CTX_use_certificate(...);
SSL_CTX_use_PrivateKey(...);

// 6. 创建SSL对象
SSL* ssl = SSL_new(ctx);

// 7. 绑定socket
SSL_set_fd(ssl, socket);

// 8. SSL握手
SSL_connect(ssl);

// 9. 发送数据
SSL_write(ssl, data, length);

// 10. 接收数据
SSL_read(ssl, buffer, size);

// 11. 清理资源
SSL_shutdown(ssl);
SSL_free(ssl);
closesocket(socket);
WSACleanup();

结论HP-Socket的封装极大简化了开发工作

实现的功能

已实现

  • Winsock初始化
  • TCP socket连接
  • SSL上下文创建和配置
  • 从内存加载证书和私钥
  • SSL双向认证SSL_VM_PEER
  • SSL握手
  • 加密数据发送
  • 加密数据接收
  • 非阻塞数据接收检查
  • 交互式命令界面
  • 资源清理

🎯 核心代码

1. 初始化SSL环境

bool InitializeSSL()
{
    // 创建SSL上下文
    g_ssl_ctx = SSL_CTX_new(TLS_client_method());
    
    // 设置验证模式
    SSL_CTX_set_verify(g_ssl_ctx, SSL_VERIFY_PEER, nullptr);
    
    // 加载CA证书
    X509* ca_cert = LoadCertFromMemory(g_c_lpszCAPemCert);
    X509_STORE* store = SSL_CTX_get_cert_store(g_ssl_ctx);
    X509_STORE_add_cert(store, ca_cert);
    
    // 加载客户端证书和私钥
    SSL_CTX_use_certificate(...);
    SSL_CTX_use_PrivateKey(...);
    
    return true;
}

2. 连接到服务器

bool ConnectToServer()
{
    // 创建TCP socket
    g_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
    // 连接到服务器
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(DEFAULT_PORT);
    inet_pton(AF_INET, DEFAULT_ADDRESS, &serverAddr.sin_addr);
    connect(g_socket, (sockaddr*)&serverAddr, sizeof(serverAddr));
    
    // 创建SSL对象并绑定socket
    g_ssl = SSL_new(g_ssl_ctx);
    SSL_set_fd(g_ssl, (int)g_socket);
    
    // 执行SSL握手
    SSL_connect(g_ssl);
    
    return true;
}

3. 发送和接收数据

// 发送
bool SendData(const std::string& data)
{
    int sent = SSL_write(g_ssl, data.c_str(), data.length());
    return sent > 0;
}

// 接收
void ReceiveData()
{
    char buffer[1024];
    int received = SSL_read(g_ssl, buffer, sizeof(buffer) - 1);
    if (received > 0) {
        buffer[received] = '\0';
        // 处理接收到的数据
    }
}

使用说明

编译

cd "E:\开发\C_C++\hp-socket-6.0.4\hp-socket-6.0.7-src\Windows\Demo\TestEcho-SSL-Console"
& "D:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" Client-Native\Client-Native.vcxproj /p:Configuration=Debug /p:Platform=x64

运行

  1. 先启动Server

    Windows\Demo\Debug\x64\TestEcho-SSL-Console-Server.exe
    
  2. 再启动Client-Native

    Windows\Demo\Debug\x64\TestEcho-SSL-Console-Client-Native.exe
    
  3. 在Client-Native中按 1 发送"hello",服务器会回复"hello!"

命令

  • 1 - 发送 "hello" 到服务器
  • q - 退出程序

技术要点

1. OpenSSL API使用

证书加载(从内存)

X509* LoadCertFromMemory(const char* certPem)
{
    BIO* bio = BIO_new_mem_buf(certPem, -1);
    X509* cert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr);
    BIO_free(bio);
    return cert;
}

私钥加载(带密码)

EVP_PKEY* LoadKeyFromMemory(const char* keyPem, const char* password)
{
    BIO* bio = BIO_new_mem_buf(keyPem, -1);
    EVP_PKEY* pkey = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, (void*)password);
    BIO_free(bio);
    return pkey;
}

SSL握手

SSL_connect(g_ssl);  // 阻塞调用,直到握手完成

2. 非阻塞I/O

为了不阻塞主循环,接收数据使用非阻塞模式:

// 设置为非阻塞
u_long mode = 1;
ioctlsocket(g_socket, FIONBIO, &mode);

// 尝试读取(不会阻塞)
int received = SSL_read(g_ssl, buffer, size);

// 恢复阻塞模式
mode = 0;
ioctlsocket(g_socket, FIONBIO, &mode);

3. 错误处理

OpenSSL的错误处理

void PrintSSLError(const char* msg)
{
    unsigned long err = ERR_get_error();
    char errBuf[256];
    ERR_error_string_n(err, errBuf, sizeof(errBuf));
    std::cout << "[错误] " << msg << ": " << errBuf << std::endl;
}

4. 资源管理

必须按顺序清理资源:

void Cleanup()
{
    if (g_ssl) {
        SSL_shutdown(g_ssl);  // 关闭SSL连接
        SSL_free(g_ssl);      // 释放SSL对象
    }
    
    if (g_socket != INVALID_SOCKET) {
        closesocket(g_socket); // 关闭socket
    }
    
    if (g_ssl_ctx) {
        SSL_CTX_free(g_ssl_ctx); // 释放SSL上下文
    }
    
    WSACleanup(); // 清理Winsock
}

依赖项

头文件

  • <winsock2.h> - Windows Socket API
  • <openssl/ssl.h> - SSL/TLS功能
  • <openssl/err.h> - 错误处理
  • <openssl/x509.h> - X.509证书
  • <openssl/bio.h> - BIO抽象
  • <openssl/pem.h> - PEM格式

库文件

  • ws2_32.lib - Winsock库
  • libssl.lib - OpenSSL SSL库
  • libcrypto.lib - OpenSSL加密库
  • crypt32.lib - Windows加密API库

路径配置

Include: E:\开发\C_C++\hp-socket-6.0.4\hp-socket-6.0.7-src\Windows\Dependent\openssl\14x\x64\include
Library: E:\开发\C_C++\hp-socket-6.0.4\hp-socket-6.0.7-src\Windows\Dependent\openssl\14x\x64\lib

学习价值

对比学习

通过Client-Native项目你可以学到

  1. 底层实现细节

    • Socket编程
    • SSL/TLS握手过程
    • 证书加载和验证
    • 加密数据传输
  2. HP-Socket的价值

    • 封装了复杂的底层细节
    • 提供简洁的API
    • 自动处理错误和资源管理
    • 跨平台支持
  3. SSL/TLS协议理解

    • 握手过程
    • 证书链验证
    • 密钥交换
    • 数据加密/解密

代码行数对比

项目 代码行数 复杂度
ClientHP-Socket ~273行
Client-Native原生 ~450行+ 中高

结论使用HP-Socket可以减少40%+的代码量!

常见问题

Q: 为什么要创建这个项目?

A: 为了学习SSL底层实现理解HP-Socket的封装价值。

Q: 实际项目应该用哪个?

A: 实际项目强烈推荐使用HP-SocketClient-Native仅用于学习。

Q: Client-Native的性能如何

A: 性能与HP-Socket相当底层都是OpenSSL但HP-Socket提供了更多优化和错误处理。

Q: 可以用Client-Native连接生产环境吗

A: 不建议。生产环境应使用成熟的库如HP-Socket而不是自己实现。

Q: 如何添加更多功能?

A: 参考HP-Socket的实现逐步添加

  • 异步I/O
  • 连接池
  • 断线重连
  • 心跳检测
  • 数据缓冲

总结

Client-Native项目是一个很好的学习工具,它帮助你理解:

  • SSL/TLS通信的底层实现
  • HP-Socket封装的价值
  • 网络编程的复杂性

但对于实际项目请使用HP-Socket或其他成熟的网络库


创建日期: 2026年1月13日
作者: AI Assistant
用途: 学习和对比
状态: 完成并可运行