VS2022配合Qt与boost.asio实现一个TCP异步通信系统远程操作mysql数据库

ops/2024/11/13 5:31:26/

        上一篇博客我们通过boost.asio搭建了一个简单的异步服务器,但是那是基于命令行的,所有用起来还是相当枯燥的,这次我们配合Qt实现一个简陋的前端页面来控制后端mysql数据库中的表,实现添加密钥的功能(本次博客使用的boost版本是1.84.0,mysql版本是8,Qt版本是6,并且本次博客主要展示代码和效果,不做代码讲解,因为本次博客所使用的代码都是之前博客中所使用过的,大家可以去我的主页学习)。

服务器端

main.cpp

#include <QtWidgets/QApplication>
#include<QtSql/QSqlDatabase>
#include<QtSql/QSqlError>
#include<QtSql/QSqlQuery>
#include<random>
#include<iostream>
#include"Server.h"
int main(int argc, char *argv[])
{QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");try{db.setPort(3306);db.setHostName("localhost");db.setDatabaseName("booksystem");db.setUserName("root");db.setPassword("2145");if (!db.open()){throw QSqlError("连接失败:", db.lastError().text());}}catch (const QSqlError &e){qDebug() << "数据库连接出错了:" << e.text();}boost::asio::io_context ioContext;Server s(ioContext, 10240);ioContext.run();return 0;
}

Server.h

#pragma once
#include"Session.h"
class Server
{
public:Server(boost::asio::io_context& ioc, int port);void start_accept();void handle_accept(Session* s,const boost::system::error_code& e);
private:boost::asio::io_context &ioc;boost::asio::ip::tcp::acceptor act;
};

Server.cpp

#include"Server.h"
Server::Server(boost::asio::io_context& ioc, int port) :ioc(ioc), act(ioc,boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4::any(), port))
{start_accept();
}
void Server::start_accept()
{Session* s = new Session(ioc);act.async_accept(s->get_socket(), std::bind(&Server::handle_accept, this, s, std::placeholders::_1));
}
void Server::handle_accept(Session* s, const boost::system::error_code& e)
{if (!e){s->Start();}else{delete s;}start_accept();
}

Session.h 

#pragma once
#include<boost/asio.hpp>
class Session
{
public:Session(boost::asio::io_context& ioc);void Start();void handle_recive(const::boost::system::error_code &e, int recived_len);void handle_send(const::boost::system:: error_code &e);boost::asio::ip::tcp::socket &get_socket();
private:boost::asio::ip::tcp::socket soc;char data[1024];int max_len = 1024;
};

Session.cpp

#include"Session.h"
#include<iostream>
#include<QtSql/QSqlQuery>
#include<QtSql/QSqlError>
Session::Session(boost::asio::io_context& ioc) :soc(ioc)
{
}
boost::asio::ip::tcp::socket & Session::get_socket()
{return this->soc;
}
void Session::Start()
{memset(data, '\0', max_len);soc.async_receive(boost::asio::buffer(data, max_len), std::bind(&Session::handle_recive, this, std::placeholders::_1, std::placeholders::_2));
}
void Session::handle_recive(const::boost::system::error_code& e, int recived_len)
{if (!e){std::cout << "recived:" << data<<std::endl;QSqlQuery q;QString sql = "insert into booksystem.secret (secrets)values(?)";q.prepare(sql);q.addBindValue(QString(data));if (!q.exec()){std::cout << "添加失败" << q.lastError().text().toStdString() << std::endl;}q.clear();//这个必须要放在async_send函数的前面,不然handle_recive函数结束的时候就会出错soc.async_send(boost::asio::buffer(data,max_len), std::bind(&Session::handle_send, this, std::placeholders::_1));}else{delete this;}
}
void Session::handle_send(const::boost::system::error_code& e)
{if (!e){memset(data, '\0', max_len);soc.async_receive(boost::asio::buffer(data, max_len), std::bind(&Session::handle_recive, this, std::placeholders::_1, std::placeholders::_2));}else{delete this;}
}

客户端

由于我们是使用VS2022作为开发平台所有并没有使用Qt Creator会使用的qmake,因此也没有对应的.pro文件,这样的好处就是,我们不必在.pro文件中配置项目的文件和第三方库了。

main.cpp

#include "QtClient.h"
#include <QtWidgets/QApplication>
#include<boost/asio.hpp>
#include<iostream>
int main(int argc, char *argv[])
{QApplication a(argc, argv);boost::asio::io_context ioContext;QtClient w(a.activeWindow(), &ioContext);try{// 创建socket对象并连接到服务器boost::asio::ip::tcp::socket socket(ioContext);boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 10240);socket.connect(endpoint);}catch (boost::system::system_error& e){std::cout<< "Exception: " << e.what() << std::endl;}w.show();return a.exec();
}

QtClient.h

#pragma once#include <QtWidgets/QWidget>
#include "ui_QtClient.h"
#include<boost/asio.hpp>
class QtClient : public QWidget
{Q_OBJECTpublic:QtClient(QWidget *parent = nullptr,boost::asio::io_context *ioc=nullptr);~QtClient();
private slots:void add_button_click();
private:Ui::QtClientClass ui;boost::asio::ip::tcp::socket soc;
};

QtClient.cpp 

#include "QtClient.h"
#include<iostream>
QtClient::QtClient(QWidget *parent,boost::asio::io_context *ioc):soc(*ioc),QWidget(parent)
{ui.setupUi(this);ui.secretText->setAlignment(Qt::AlignCenter);soc.connect(boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 10240));connect(ui.addButton, &QPushButton::clicked, this, &QtClient::add_button_click);
}QtClient::~QtClient()
{}
void QtClient::add_button_click()
{std::cout << "secret get: " << ui.secretText->text().toUtf8().toStdString()<< std::endl;QByteArray d = ui.secretText->text().toUtf8();char data[1024] = "";qstrcpy(data, d.data());soc.send(boost::asio::buffer(data));char rec[1024] = "";soc.receive(boost::asio::buffer(rec, 1024));std::cout << "reply:" << rec << std::endl;
}

ui_QtClient.h

/********************************************************************************
** Form generated from reading UI file 'QtClient.ui'
**
** Created by: Qt User Interface Compiler version 6.6.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/#ifndef UI_QTCLIENT_H
#define UI_QTCLIENT_H#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>QT_BEGIN_NAMESPACEclass Ui_QtClientClass
{
public:QPushButton *addButton;QLineEdit *secretText;void setupUi(QWidget *QtClientClass){if (QtClientClass->objectName().isEmpty())QtClientClass->setObjectName("QtClientClass");QtClientClass->resize(600, 400);QtClientClass->setStyleSheet(QString::fromUtf8("background-color: rgb(255, 170, 255);"));addButton = new QPushButton(QtClientClass);addButton->setObjectName("addButton");addButton->setGeometry(QRect(220, 220, 151, 51));addButton->setStyleSheet(QString::fromUtf8("background-color: rgb(85, 255, 255);\n"
"font: 12pt \"Microsoft YaHei UI\";\n"
"border: 3 solid rgb(0, 0, 255);"));secretText = new QLineEdit(QtClientClass);secretText->setObjectName("secretText");secretText->setGeometry(QRect(80, 110, 441, 71));secretText->setStyleSheet(QString::fromUtf8("font: 16pt \"Microsoft YaHei UI\";\n"
"background-color: rgb(0, 255, 127);\n"
"border:3 solid rgb(0, 170, 0);"));retranslateUi(QtClientClass);QMetaObject::connectSlotsByName(QtClientClass);} // setupUivoid retranslateUi(QWidget *QtClientClass){QtClientClass->setWindowTitle(QCoreApplication::translate("QtClientClass", "QtClient", nullptr));addButton->setText(QCoreApplication::translate("QtClientClass", "\346\267\273\345\212\240\345\257\206\351\222\245", nullptr));secretText->setPlaceholderText(QCoreApplication::translate("QtClientClass", "\350\257\267\350\276\223\345\205\245\345\257\206\351\222\245", nullptr));} // retranslateUi};namespace Ui {class QtClientClass: public Ui_QtClientClass {};
} // namespace UiQT_END_NAMESPACE#endif // UI_QTCLIENT_H

运行效果

显然左边的窗口是服务器窗口,右边两个窗口是客户端的界面窗口和控制台窗口,有的人因为项目属性配置的问题,可能只有界面窗口,不过没什么影响啦。

输入我们要添加的密钥后,点击添加按钮,发现服务器成功添加了密钥,并且向客户端发送了响应,并且客户端也接收到了响应。

 打开mysql里面的secret表,发现我们的密钥添加进去了。


http://www.ppmy.cn/ops/42368.html

相关文章

数据中台在制造业中的应用及其转型价值_光点科技

在数字化时代&#xff0c;制造业正面临前所未有的挑战与机遇。随着大数据、云计算、物联网等技术的发展&#xff0c;数据中台已经成为制造业企业转型的重要驱动力。数据中台制造业的概念越来越受到行业的关注&#xff0c;它代表着数据技术和制造业深度融合的新趋势。本文将深入…

【Qt】如何优雅的进行界面布局

文章目录 1 :peach:写在前面:peach:2 :peach:垂直布局:peach:3 :peach:水平布局:peach:4 :peach:网格布局:peach:5 :peach:表单布局:peach: 1 &#x1f351;写在前面&#x1f351; 之前使⽤ Qt 在界⾯上创建的控件, 都是通过 “绝对定位” 的⽅式来设定的。也就是每个控件所在…

Dispossessor 勒索软件是否会成为 LockBit 的接班者

最近浮出水面的 Dispossessor 勒索软件&#xff0c;其与臭名昭著的 LockBit 勒索软件团伙存在许多相似之处。在全球执法机构联合打击了 LockBit 的攻击基础设施后&#xff0c;Dispossessor 带着与 LockBit 高度相似的结构与内容出现在众人眼前。 Dispossessor 符号标记 Dispos…

驱动未来:IT行业的现状与发展趋势

前言 随着技术的不断进步&#xff0c;IT行业已成为推动全球经济和社会发展的关键力量。从云计算、大数据、人工智能到物联网、5G通信和区块链&#xff0c;这些技术正在重塑我们的生活和工作方式。本文将探讨IT行业的现状和未来发展趋势&#xff0c;并邀请行业领袖、技术专家和…

go全部版本下载目录

linux安装教程&#xff1a; Download and install - The Go Programming Language rm -rf /usr/local/go && tar -C /usr/local -xzf go1.22.3.linux-amd64.tar.gzexport PATH$PATH:/usr/local/go/bin go version 全部版本下载目录&#xff1a; All releases - Th…

(1)无线电失控保护(二)

文章目录 前言 4 参数配置 5 测试 6 使用接收器设置飞行模式(

Android Audio基础——AudioFlinger音频流管理(八)

从前面 AudioTrack、PlaybackThread、输出流设备三者的关系中,我们看到 AudioTrack 把音频流数据送入到对应的 PlaybackThread 中,那么应用进程是如何控制音频流的开始播放 start()、停止播放 stop()、暂停播放 pause()。这一章节我们就来继续分析。 一、音频流管理 应用进程…

PHP在线制作表白网源码

PHP在线制作表白网源码&#xff0c;送女友个惊喜吧&#xff0c;无数据库&#xff0c;上传就能用&#xff0c;后台/admin&#xff0c;账号密码都是admin 百度网盘&#xff1a;https://pan.baidu.com/s/1rbD2_8IsP9UPLK-cdgEXfA?pwdre59