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

        上一篇博客我们通过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.mzph.cn/news/842189.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构的直接插入排序(C语言版)

一.直接插入排序的基本概念 1.直接插入排序的基本思想 将数组分为已排序和未排序两部分。 每次从未排序部分取出一个元素,将其插入到已排序部分的合适位置,使得已排序部分保持有序。 重复步骤2,直到整个数组有序。 2.排序的工作原理 假设前 i-1 个元素已经有序,现在要将第…

前端开发的设计思路【精炼】(含数据结构设计、组件设计)

数据结构设计 用数据描述所有的内容数据要结构化&#xff0c;易于程序操作(遍历、查找)&#xff0c;比如数组、对象、对象为元素构成的数组&#xff08;每个元素记得设置唯一的 id 属性&#xff0c;以便对元素进行删改操作&#xff09;数据要可扩展&#xff0c;以便增加新的功能…

设置 border 边框单侧样式 - HarmonyOSNext

设置 border 边框单侧样式,通过 api 中查看 border(value: BorderOptions): T; BorderOptions 又包含了若干个子属性 1.width?: EdgeWidths | Length; 2.color?: EdgeColors | ResourceColor; 3.radius?: BorderRadiuses | Length; 4.style?: EdgeStyles | BorderStyle; 其…

MYSQL框架结构

MYSQL框架结构 通过解析器和预处理生成解析树&#xff0c;预处理判断是否合法&#xff0c;如果合法则调用优化器去进行优化。

World Creator v2.1.0 解锁版安装教程 (GPU三维地形生成软件)

前言 World Creator是一款功能相当强大的地形景观生成器&#xff1b;可以完全根据自己的需求来对地形、景观生成您需要三维模型&#xff0c;内置的大量预设&#xff0c;让您的创建拥有无限的可能性。 一、下载地址 下载链接&#xff1a;http://dygod/ITSource 点击搜索&…

蓝卓入选工信部2023年度“揭榜挂帅”项目

蓝卓“面向多元异构和应用快速开发演化的智能工厂操作系统解决方案”&#xff0c;凭借行业领先的平台技术能力以及数智赋能的硬核实力成功揭榜挂帅。 本次入选不仅代表了蓝卓又一次获得工信部权威专家及国家认可&#xff0c;更是“工厂操作系统”首次在国家层面获得表彰。 智能…

【JS】async/await异常捕获,这样做才完美

前言 &#x1f34a;缘由 JS中async/await异步调用&#xff0c;只能通过try-catch吗&#xff1f; &#x1f34d;你想听的故事&#xff1a; 作为一个合格的全栈搬砖工&#xff0c;那必须文武双全&#xff0c;前后必备。遂吾日三省吾身&#xff0c;偶发觉前端长时间不写有些落下…

宝塔Nginx设置图片访问跨域

宝塔Nginx设置图片访问跨域 针对某一个站点设置 找到对应的站点点击 “设置” 增加对应header设置 代码&#xff1a; location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)${#允许跨域add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Headers X-Requeste…

【NumPy】关于numpy.subtract()函数,看这一篇文章就够了

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

【全开源】活动报名表单系统(ThinkPHP+Uniapp+uView)

轻松构建高效报名平台 一、引言 随着线上活动的日益增多&#xff0c;一个高效、易用的活动报名表单系统成为了举办各类活动的必备工具。为了满足不同组织和个人的需求&#xff0c;我们推出了功能强大的“活动报名表单系统源码”。本文将为您详细介绍该源码的特点、功能以及使…

【UE数字孪生学习笔记】 使用DataSmith对模型快速导入 UE5.3.2使用unreal DataSmith文件

声明&#xff1a;部分内容来自于b站&#xff0c;慕课&#xff0c;公开课等的课件&#xff0c;仅供学习使用。如有问题&#xff0c;请联系删除。 部分内容来自UE官方文档&#xff0c;博客等 UE5.3.2使用 3D Max 导出的unreal DataSmith文件 1. 去UE官网下载DataSmith导出器并导…

【Linux】中常见的重要指令(下)以及重要的几个热键

目录 一、时间相关的指令date 1.时间戳 二、Cal指令 三、find指令 1.whereis 2.which 四、grep指令 五、zip和unzip指令 六、tar指令 七、bc指令 八、.重要的几个热键[Tab]&#xff0c;[ctrl]-c&#xff0c;[ctrl]-d 一、时间相关的指令date date 指定格式显示时间…

ROM的简单实现

描述 实现一个深度为8&#xff0c;位宽为4bit的ROM&#xff0c;数据初始化为0&#xff0c;2&#xff0c;4&#xff0c;6&#xff0c;8&#xff0c;10&#xff0c;12&#xff0c;14。可以通过输入地址addr&#xff0c;输出相应的数据data。 接口信号图如下&#xff1a; 使用Veri…

Esp32+阿里云物联网平台+DHT11+控制LED(基于PubSubClient库)

Esp32阿里云物联网平台DHT11控制LED 关于本文&#xff1a;利用ESP32连接DHT11温湿度传感器获取温湿度&#xff0c;上报到阿里云物联网平台&#xff0c;通过阿里云物联网平台实时远程查看温湿度&#xff0c;并且接收平台下发的LED灯控制指令。要注意的是&#xff0c;阿里云有两…

【动态规划】零基础解决路径问题(C++)

目录 62.路径问题 解法&#xff08;动态规划&#xff09;&#xff1a; 1. 状态表⽰&#xff1a; 2. 状态转移⽅程&#xff1a; 3. 初始化&#xff1a; 4. 填表顺序&#xff1a; 5. 返回值&#xff1a; 不同路径2.0 解法&#xff08;动态规划&#xff09;&#xff1a; …

22-LINUX--多线程and多进程TCP连接

一.TCP连接基础知识 1.套接字 所谓套接字(Socket)&#xff0c;就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端&#xff0c;提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲&#xff0c;套接字上联应用进程…

React 中Redux结合React-Redux使用类组件版本(一)

一、Redux是什么&#xff1f; 1.Redux是一个专门用于状态管理的js库 2.它可以用在React、Angular、Vue的项目中&#xff0c;但基本与React配合使用。 3.作用&#xff1a;集中式管理React应用中多个组件共享的状态。 二、Redux 工作流程 三、Redux的三个核心概念 1.action 动…

振弦采集仪在岩土工程监测中的精度与可靠性评估

振弦采集仪在岩土工程监测中的精度与可靠性评估 河北稳控科技振弦采集仪是一种常用的岩土工程土体力学参数监测仪器&#xff0c;它主要用于测量岩土中的应力、应变和模量等力学参数。在岩土工程中&#xff0c;土体力学参数的精确测量对于工程设计、施工和监测都非常重要。因此…

前缀和算法专题

应用: 计算数组中某区间的和 一. 一维前缀和[模版] 答案 二. 二维前缀和[模版] 答案 三. 寻找数组的中心下标 答案 四. 除自身以外数组的乘积 答案 五. 和为k的子数组 答案 六. 和可被k整除的子数组 答案 七. 连续数组 答案 八. 矩阵区域和 答案

如何查看网站的cookie?

前言&#xff1a; 在网络世界中&#xff0c;cookie是一种常见的信息存储方式。 对于开发者和普通用户来说&#xff0c;了解如何查看CSDN的cookie是非常重要的。 本文将介绍几种常用的方法&#xff0c;帮助大家更好地理解和使用cookie&#xff1a; 代码示例&#xff1a; 通过浏…