备份-基础ssl通信
This commit is contained in:
461
Client-Native/main.cpp.backup
Normal file
461
Client-Native/main.cpp.backup
Normal file
@@ -0,0 +1,461 @@
|
||||
// TestEcho-SSL-Console Client-Native
|
||||
// 纯OpenSSL+Winsock实现的SSL客户端(不使用HP-Socket)
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// SSL证书配置(与Client项目相同)
|
||||
static const char* g_c_lpszPemCert =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDszCCApugAwIBAgIBATANBgkqhkiG9w0BAQsFADB7MQswCQYDVQQGEwJDTjEL\n"
|
||||
"MAkGA1UECAwCR0QxCzAJBgNVBAcMAkdaMQwwCgYDVQQKDANTU1QxDzANBgNVBAsM\n"
|
||||
"Bkplc3NtYTETMBEGA1UEAwwKamVzc21hLm9yZzEeMBwGCSqGSIb3DQEJARYPbGRj\n"
|
||||
"c2FhQDIxY24uY29tMCAXDTI0MDYyNjA1MjUwOFoYDzIyNDMwNzA5MDUyNTA4WjBu\n"
|
||||
"MQswCQYDVQQGEwJDTjELMAkGA1UECAwCR0QxDDAKBgNVBAoMA1NTVDEPMA0GA1UE\n"
|
||||
"CwwGSmVzc21hMRMwEQYDVQQDDApqZXNzbWEub3JnMR4wHAYJKoZIhvcNAQkBFg9s\n"
|
||||
"ZGNzYWFAMjFjbi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCD\n"
|
||||
"+MyrJEKCheRoOpMRjR78S8hr9W7XN0/EZWyVKwXRT7EE0aGiQdH/W2a+qpWRMa6E\n"
|
||||
"Qi47zdBnt0P8ZoFiItQhuhwUJ064afpVoaHHX25UdbF8r+sRTofadughETBBj2Cf\n"
|
||||
"qh0ia6EOB0QvpJpywWmGZPoMtypjbUiTb/YGOJh2qsVr67MN/E48vt7qt0VxF9SE\n"
|
||||
"pucvqhraTBljWCeRVCae2c0yBSpq/n+7NhamK7+g3xxCKWRz4pN3wrIoEsXTboTh\n"
|
||||
"z940caDgthCc23VJ080DN44jZg6c87huKIuxbebJqw2HCM4DwrW+OSzTLszpFAXZ\n"
|
||||
"yarllOzWnBut20zmYnl1AgMBAAGjTTBLMAkGA1UdEwQCMAAwHQYDVR0OBBYEFJ5E\n"
|
||||
"RJmJ4pUzEbcU9Yge6nr0oi51MB8GA1UdIwQYMBaAFN49z48DywmoD4cNTQgC6nn2\n"
|
||||
"QJoUMA0GCSqGSIb3DQEBCwUAA4IBAQBpoSFfDDDKMAy95tSROpYu5WSWQXe6B7kl\n"
|
||||
"PGJAF6mWe/4b7jHQqDUVkEmFmbMWUAtpTC3P01TrV77dhIosAnC/B76fb7Pto8W4\n"
|
||||
"cjGpWAT0sSegZuhnLtguTGlnR0vVSh/yRRDEtjN8loWpu3BLWVHYOKnn62QGfY0B\n"
|
||||
"sRGrfZsKvwB+1w+HOvGopnWv6UYwrzEKthjPMR65rOsoManOv24ua8baJmq0gqF9\n"
|
||||
"752kD8n703uWUBx79/QlNIPMZC1iUIi1mEjyrTgSag6+3sWAIKihaoF/Nf9d01nw\n"
|
||||
"iL16EIT5dJ0QJWDCeIxhuTZckw+gL1pBeQU7pqzKHPnvo+8GBnTG\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char* g_c_lpszPemKey =
|
||||
"-----BEGIN ENCRYPTED PRIVATE KEY-----\n"
|
||||
"MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIK2UJW9QXIj4CAggA\n"
|
||||
"MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBCDDZQLhAdT91jd6v/5H0+GBIIE\n"
|
||||
"0PH6tKl+nPi8sU0ryjxDIrHwrT/ZFah+3TAHGE/YFAOZnzRyCFHQTvUZX4p8eSmw\n"
|
||||
"WOpt5NBUPJ3mT0Ctt7lGBRy4AXSyBrFSamlTruM3P1e3ijluYjMbweZFfCWPq8c/\n"
|
||||
"jPjbcUkXe6mD96aPSTt/jIunexS8AKovu8c/bFLyTLDk38lATc+GnXQQJ0KiXCRu\n"
|
||||
"vpjVSKcv2Br6cWqaNTZ71FvH1RmSD6K6givc0w65pKruHYTMApIRR8YC5Y0vx0gD\n"
|
||||
"6nS12LV/EJEtxTfZFlrzZTRWZISPIzYGuTfS+3bPePlxpbwzhN6vmvgjKhdk+3lN\n"
|
||||
"3W3ZfqODNhoOKG+mG5Fdj7vR2PU1UND6UUd3+FrzWkXikmalAAwKzRLnyTR1T2rl\n"
|
||||
"RhM0Qe/HZianeEQTHpCw27gOz1OMw2EKfIEHM6W2BKGOTY5ls5dqgMfP1ZoQUrOr\n"
|
||||
"59tJo4GpWYFGCuHhTEa5OS/gsgnzymGrkuEwPsdSQaBdzV7lFGTv2/ryKX+vNm9V\n"
|
||||
"CmKw0nHzOVP19+WL4vPDtbRnLUk8KV9Mg7PdSbGbNcMmTEBk8ju8OvjIUIWZbRTa\n"
|
||||
"n5C6fhD1DYZcczmlCILYgXyJISu7EDf3z9cKRAf5VbRAedDMB/xHWmrmlxUJ37Kt\n"
|
||||
"tVgaCD0U6Q3q+3y6OOwugc8UbSo4yA/DbLlG0/U7afwQaNxTLa4HGBQljpoNStIt\n"
|
||||
"Vgfy2olqHXaf2doSQtsYEl9MHa6neuGfZQMtonDkejnx4KKU+cMhe+KijEUwieYx\n"
|
||||
"7aoPB71b82XODquDPAL5zOegj0eYgKn5iXyOx5W44S34zfclxtxxgfsDJ3qJ9qoL\n"
|
||||
"sSenrQ3xAYHJSZRcqEgO31XhoEnkyt1V7G0Bk4/GUMD6uQudr3nsw/ulJpAlNK15\n"
|
||||
"ZxTSKWrtwOWdwcTj6B14K6wcqMFVNF1Ydbv/qp0b5q5S/orYHzRIPcFmdOAIsjyO\n"
|
||||
"6na7+D31BH/4pf+TASBNqRNRw5CBqNcGcfiXk11AywxUnmD5ZvC/C0pTpTD/9qC4\n"
|
||||
"LucWJ0sNAtPq8suFjKqQ+wMvq3rUh050NRm2cm2nUJLxafTnr0v3+kKYbVW8pSWB\n"
|
||||
"NMelZMVGF1MDYBujg8Mw/xuMhPeLozCZeKmo7eu7aDMXzQMZLfAEJAzU9Du8H4nq\n"
|
||||
"GgQVUgEkS5rdbjZGkHP0FuM8m8lueKEPDYwHCJv9Be5Z/uxp9OO/Lmdlha0J7gJu\n"
|
||||
"pihNkAYVxRst96b5okXKooYi/TZxAdThoPYH28VwinGR1I3/8I3M5DbUPIgHhDeB\n"
|
||||
"ga3u7jt7ZNDUgavukUD0S7WioRb5ooXrXGZ1xmzKLCmMdCDC5S32fQS0wRGfVoMl\n"
|
||||
"hWbaT+0uak+fOpqVRxSNyE3Ek788ua5iPHaTSXJSoe5lv7OQKDSZ/+wFeLmDPf4M\n"
|
||||
"BHL2gBLD6RNkz5cWgy14sQcJKNAnyptU4EGPyURZcB8APtB/ITAS2Az/JSxvSBgq\n"
|
||||
"g/L1FujnP2QEpWpVKkTNxsF867bUPN34KrlPKYjNqcKA2pD4fkFoKSeeNtOEWa++\n"
|
||||
"d6q9y+mDD97SnIFAAhDFlukzXtyl4MU6uiqRldFiuEt3KzvV19n8M+NyyYIFhfdg\n"
|
||||
"6TkYEbMJPQ/Y3EGNmyMqbFdJzrdl/B8pr7JQnikTfUZZ\n"
|
||||
"-----END ENCRYPTED PRIVATE KEY-----\n";
|
||||
|
||||
static const char* g_c_lpszCAPemCert =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIID2TCCAsGgAwIBAgIUM8TTtPU+ejzffYXCcs/zZsU7OuIwDQYJKoZIhvcNAQEL\n"
|
||||
"BQAwezELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkdEMQswCQYDVQQHDAJHWjEMMAoG\n"
|
||||
"A1UECgwDU1NUMQ8wDQYDVQQLDAZKZXNzbWExEzARBgNVBAMMCmplc3NtYS5vcmcx\n"
|
||||
"HjAcBgkqhkiG9w0BCQEWD2xkY3NhYUAyMWNuLmNvbTAgFw0yNDA2MjYwNTA0NDNa\n"
|
||||
"GA8yMjcwMTEyNDA1MDQ0M1owezELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkdEMQsw\n"
|
||||
"CQYDVQQHDAJHWjEMMAoGA1UECgwDU1NUMQ8wDQYDVQQLDAZKZXNzbWExEzARBgNV\n"
|
||||
"BAMMCmplc3NtYS5vcmcxHjAcBgkqhkiG9w0BCQEWD2xkY3NhYUAyMWNuLmNvbTCC\n"
|
||||
"ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAML+v79+aLQt0Za0dTIZHI5B\n"
|
||||
"NDs0g5G8bhdOTlW/kNWflaziZ3GY6d6nJSkQ5e29kyFKxlOD6Gls6bOJ86U71u4R\n"
|
||||
"bCmoFvRTDH4q2cJ/+PbiioLpNveDG6lnRCs9JNRQoJrkpRo6urnVnAdsIf6UFjLI\n"
|
||||
"dlByNMPGYJ0V8/oKJG5Vu5gcbZV0jVA5+tswkH/zquexEXoKvp18mcwl+pNc/LwW\n"
|
||||
"0WnGj0uoJjxHg4GsS78PASjhxMR/2d/1OpgPauldFaNHjVPtaLqJnuejwA6M6Sz8\n"
|
||||
"iFPybAQAMpHL9W8kf08jtbnFvnm4ibUkQL5h+OJoIEQa9AVZOSoFG2/g5Zcn8X8C\n"
|
||||
"AwEAAaNTMFEwHQYDVR0OBBYEFN49z48DywmoD4cNTQgC6nn2QJoUMB8GA1UdIwQY\n"
|
||||
"MBaAFN49z48DywmoD4cNTQgC6nn2QJoUMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI\n"
|
||||
"hvcNAQELBQADggEBALJnYrYBSZLyYX14FQ04zxG3AX0CtQzNOOa7LDrr+H8Ly+nK\n"
|
||||
"qS87gg2njMVZH1zM2demtMwydR/F2Ui8ggaduMvc9h5YgQKEwYl8KarJEY03oZoe\n"
|
||||
"zbQGBxCXpDOtMs1vujzcl/iZbSzwEDF3g4la5U8q4MlmfGFKz9CJbvoxecqYA206\n"
|
||||
"nNbW2XZsW/xMiQv6iAw5iP/LOR9HAyxcvXIsL790nfcgnTYLmyP254Dj4outc6R+\n"
|
||||
"PA+f/c1FvkbUBTR5vJt2tsvHcNU218rY2hyOIhDmZeUWprqBO19sUk3scLbVPr3+\n"
|
||||
"WEWEl2XaCekKuPtAnMgVQuFsocXGyiuIhkOe5Z4=\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char* g_c_lpszKeyPassword = "123456";
|
||||
static const char* DEFAULT_ADDRESS = "127.0.0.1";
|
||||
static const int DEFAULT_PORT = 5555;
|
||||
|
||||
// 全局变量
|
||||
SSL_CTX* g_ssl_ctx = nullptr;
|
||||
SSL* g_ssl = nullptr;
|
||||
SOCKET g_socket = INVALID_SOCKET;
|
||||
|
||||
// 打印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;
|
||||
}
|
||||
|
||||
// 从内存加载证书
|
||||
X509* LoadCertFromMemory(const char* certPem)
|
||||
{
|
||||
BIO* bio = BIO_new_mem_buf(certPem, -1);
|
||||
if (!bio) {
|
||||
PrintSSLError("创建BIO失败");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
X509* cert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr);
|
||||
BIO_free(bio);
|
||||
|
||||
if (!cert) {
|
||||
PrintSSLError("读取证书失败");
|
||||
}
|
||||
|
||||
return cert;
|
||||
}
|
||||
|
||||
// 从内存加载私钥
|
||||
EVP_PKEY* LoadKeyFromMemory(const char* keyPem, const char* password)
|
||||
{
|
||||
BIO* bio = BIO_new_mem_buf(keyPem, -1);
|
||||
if (!bio) {
|
||||
PrintSSLError("创建BIO失败");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EVP_PKEY* pkey = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, (void*)password);
|
||||
BIO_free(bio);
|
||||
|
||||
if (!pkey) {
|
||||
PrintSSLError("读取私钥失败");
|
||||
}
|
||||
|
||||
return pkey;
|
||||
}
|
||||
|
||||
// 初始化OpenSSL
|
||||
bool InitializeSSL()
|
||||
{
|
||||
// OpenSSL 1.1.0+ 自动初始化,不需要手动调用初始化函数
|
||||
|
||||
// 创建SSL上下文(使用TLS客户端方法)
|
||||
g_ssl_ctx = SSL_CTX_new(TLS_client_method());
|
||||
if (!g_ssl_ctx) {
|
||||
PrintSSLError("创建SSL上下文失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 设置验证模式:验证服务器证书
|
||||
SSL_CTX_set_verify(g_ssl_ctx, SSL_VERIFY_PEER, nullptr);
|
||||
|
||||
// 加载CA证书(用于验证服务器)
|
||||
BIO* ca_bio = BIO_new_mem_buf(g_c_lpszCAPemCert, -1);
|
||||
if (!ca_bio) {
|
||||
PrintSSLError("创建CA BIO失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
X509* ca_cert = PEM_read_bio_X509(ca_bio, nullptr, nullptr, nullptr);
|
||||
BIO_free(ca_bio);
|
||||
|
||||
if (!ca_cert) {
|
||||
PrintSSLError("读取CA证书失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 将CA证书添加到信任列表
|
||||
X509_STORE* store = SSL_CTX_get_cert_store(g_ssl_ctx);
|
||||
if (X509_STORE_add_cert(store, ca_cert) != 1) {
|
||||
PrintSSLError("添加CA证书失败");
|
||||
X509_free(ca_cert);
|
||||
return false;
|
||||
}
|
||||
X509_free(ca_cert);
|
||||
|
||||
// 加载客户端证书
|
||||
X509* client_cert = LoadCertFromMemory(g_c_lpszPemCert);
|
||||
if (!client_cert) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SSL_CTX_use_certificate(g_ssl_ctx, client_cert) != 1) {
|
||||
PrintSSLError("使用客户端证书失败");
|
||||
X509_free(client_cert);
|
||||
return false;
|
||||
}
|
||||
X509_free(client_cert);
|
||||
|
||||
// 加载客户端私钥
|
||||
EVP_PKEY* client_key = LoadKeyFromMemory(g_c_lpszPemKey, g_c_lpszKeyPassword);
|
||||
if (!client_key) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SSL_CTX_use_PrivateKey(g_ssl_ctx, client_key) != 1) {
|
||||
PrintSSLError("使用客户端私钥失败");
|
||||
EVP_PKEY_free(client_key);
|
||||
return false;
|
||||
}
|
||||
EVP_PKEY_free(client_key);
|
||||
|
||||
// 验证私钥和证书是否匹配
|
||||
if (SSL_CTX_check_private_key(g_ssl_ctx) != 1) {
|
||||
std::cout << "[错误] 客户端私钥和证书不匹配" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "[客户端] SSL环境初始化成功" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 初始化Winsock
|
||||
bool InitializeWinsock()
|
||||
{
|
||||
WSADATA wsaData;
|
||||
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
if (result != 0) {
|
||||
std::cout << "[错误] WSAStartup失败,错误码: " << result << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 连接到服务器
|
||||
bool ConnectToServer()
|
||||
{
|
||||
// 创建socket
|
||||
g_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (g_socket == INVALID_SOCKET) {
|
||||
std::cout << "[错误] 创建socket失败,错误码: " << WSAGetLastError() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 设置服务器地址
|
||||
sockaddr_in serverAddr;
|
||||
serverAddr.sin_family = AF_INET;
|
||||
serverAddr.sin_port = htons(DEFAULT_PORT);
|
||||
inet_pton(AF_INET, DEFAULT_ADDRESS, &serverAddr.sin_addr);
|
||||
|
||||
// 连接到服务器
|
||||
std::cout << "[客户端] 正在连接服务器 " << DEFAULT_ADDRESS << ":" << DEFAULT_PORT << " ..." << std::endl;
|
||||
if (connect(g_socket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
|
||||
std::cout << "[错误] 连接失败,错误码: " << WSAGetLastError() << std::endl;
|
||||
closesocket(g_socket);
|
||||
g_socket = INVALID_SOCKET;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "[客户端] TCP连接成功" << std::endl;
|
||||
|
||||
// 创建SSL对象
|
||||
g_ssl = SSL_new(g_ssl_ctx);
|
||||
if (!g_ssl) {
|
||||
PrintSSLError("创建SSL对象失败");
|
||||
closesocket(g_socket);
|
||||
g_socket = INVALID_SOCKET;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 将SSL绑定到socket
|
||||
if (SSL_set_fd(g_ssl, (int)g_socket) != 1) {
|
||||
PrintSSLError("绑定SSL到socket失败");
|
||||
SSL_free(g_ssl);
|
||||
g_ssl = nullptr;
|
||||
closesocket(g_socket);
|
||||
g_socket = INVALID_SOCKET;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 执行SSL握手
|
||||
std::cout << "[客户端] 正在进行SSL握手..." << std::endl;
|
||||
int ret = SSL_connect(g_ssl);
|
||||
if (ret != 1) {
|
||||
int err = SSL_get_error(g_ssl, ret);
|
||||
std::cout << "[错误] SSL握手失败,错误码: " << err << std::endl;
|
||||
PrintSSLError("SSL_connect");
|
||||
SSL_free(g_ssl);
|
||||
g_ssl = nullptr;
|
||||
closesocket(g_socket);
|
||||
g_socket = INVALID_SOCKET;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "[客户端] SSL握手完成!" << std::endl;
|
||||
|
||||
// 显示SSL信息
|
||||
std::cout << "[客户端] 使用的加密套件: " << SSL_get_cipher(g_ssl) << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 发送数据
|
||||
bool SendData(const std::string& data)
|
||||
{
|
||||
if (!g_ssl) {
|
||||
std::cout << "[错误] SSL未初始化" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
int sent = SSL_write(g_ssl, data.c_str(), (int)data.length());
|
||||
if (sent <= 0) {
|
||||
int err = SSL_get_error(g_ssl, sent);
|
||||
std::cout << "[错误] 发送失败,错误码: " << err << std::endl;
|
||||
PrintSSLError("SSL_write");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "[客户端] 发送数据: \"" << data << "\" (" << sent << " 字节)" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 接收数据(非阻塞检查)
|
||||
void ReceiveData()
|
||||
{
|
||||
if (!g_ssl) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置socket为非阻塞模式
|
||||
u_long mode = 1;
|
||||
ioctlsocket(g_socket, FIONBIO, &mode);
|
||||
|
||||
char buffer[1024];
|
||||
int received = SSL_read(g_ssl, buffer, sizeof(buffer) - 1);
|
||||
|
||||
if (received > 0) {
|
||||
buffer[received] = '\0';
|
||||
std::cout << "[客户端] 收到数据: \"" << buffer << "\" (" << received << " 字节)" << std::endl;
|
||||
}
|
||||
else if (received < 0) {
|
||||
int err = SSL_get_error(g_ssl, received);
|
||||
if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
|
||||
// 真正的错误(不是"没有数据")
|
||||
if (err != SSL_ERROR_ZERO_RETURN) { // 忽略正常关闭
|
||||
std::cout << "[错误] 接收失败,错误码: " << err << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 恢复为阻塞模式
|
||||
mode = 0;
|
||||
ioctlsocket(g_socket, FIONBIO, &mode);
|
||||
}
|
||||
|
||||
// 清理资源
|
||||
void Cleanup()
|
||||
{
|
||||
if (g_ssl) {
|
||||
SSL_shutdown(g_ssl);
|
||||
SSL_free(g_ssl);
|
||||
g_ssl = nullptr;
|
||||
}
|
||||
|
||||
if (g_socket != INVALID_SOCKET) {
|
||||
closesocket(g_socket);
|
||||
g_socket = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if (g_ssl_ctx) {
|
||||
SSL_CTX_free(g_ssl_ctx);
|
||||
g_ssl_ctx = nullptr;
|
||||
}
|
||||
|
||||
WSACleanup();
|
||||
}
|
||||
|
||||
// 打印菜单
|
||||
void PrintMenu()
|
||||
{
|
||||
std::cout << "\n命令菜单:" << std::endl;
|
||||
std::cout << " 1 - 发送 \"hello\"" << std::endl;
|
||||
std::cout << " q - 退出程序" << std::endl;
|
||||
std::cout << "请输入命令: " << std::flush;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// 设置控制台UTF-8编码
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
std::locale::global(std::locale(""));
|
||||
|
||||
std::cout << "========================================" << std::endl;
|
||||
std::cout << " SSL Client Native (纯OpenSSL+Winsock)" << std::endl;
|
||||
std::cout << "========================================" << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// 初始化Winsock
|
||||
if (!InitializeWinsock()) {
|
||||
std::cout << "按任意键退出..." << std::endl;
|
||||
_getch();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 初始化SSL
|
||||
if (!InitializeSSL()) {
|
||||
std::cout << "按任意键退出..." << std::endl;
|
||||
_getch();
|
||||
Cleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 连接到服务器
|
||||
if (!ConnectToServer()) {
|
||||
std::cout << "按任意键退出..." << std::endl;
|
||||
_getch();
|
||||
Cleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "[客户端] 已连接到服务器,可以开始发送消息" << std::endl;
|
||||
|
||||
// 主循环
|
||||
PrintMenu();
|
||||
|
||||
bool running = true;
|
||||
while (running) {
|
||||
// 检查是否有数据可接收
|
||||
ReceiveData();
|
||||
|
||||
// 检查键盘输入
|
||||
if (_kbhit()) {
|
||||
char ch = _getch();
|
||||
std::cout << ch << std::endl;
|
||||
|
||||
if (ch == '1') {
|
||||
// 发送 "hello"
|
||||
if (SendData("hello")) {
|
||||
Sleep(100); // 等待一下让服务器响应
|
||||
ReceiveData(); // 接收响应
|
||||
}
|
||||
PrintMenu();
|
||||
}
|
||||
else if (ch == 'q' || ch == 'Q') {
|
||||
running = false;
|
||||
}
|
||||
else {
|
||||
std::cout << "无效命令,请重新输入。" << std::endl;
|
||||
PrintMenu();
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(100);
|
||||
}
|
||||
|
||||
// 清理资源
|
||||
std::cout << "[客户端] 正在断开连接..." << std::endl;
|
||||
Cleanup();
|
||||
std::cout << "[客户端] 已断开连接" << std::endl;
|
||||
|
||||
std::cout << "按任意键退出..." << std::endl;
|
||||
_getch();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user