libevent服务器附带qt界面开发(附带源码)

本章是入门章节,讲解如何实现一个附带界面的服务器,后续会完善与优化

  • 使用qt编译libevent
  • 源码
  • 演示视频
  • qt的一些知识

在这里插入图片描述
1.主要功能有登录界面
2.基于libevent实现的服务器的业务功能

使用qt编译libevent

下载这个,其他版本也可以
主要是github上下载,可能有点卡
链接: link
在这里插入图片描述
在这里插入图片描述
编译流程
1.打开qt然后点下面的红框
在这里插入图片描述
2.选cmakelist
在这里插入图片描述
3.选编译器在这里插入图片描述
4.最后一步编译
在这里插入图片描述
5.编译成功后库的位置
在这里插入图片描述
在这里插入图片描述
最后编译成功后可以丢到/usr/bin里也可以丢到自己的写的程序的目录下

源码

源码结构如下
在这里插入图片描述
下面是libeventuse.cpp

#include "libeventuse.h"
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#ifndef _WIN32
#include <netinet/in.h>
# ifdef _XOPEN_SOURCE_EXTENDED
#  include <arpa/inet.h>
# endif
#include <sys/socket.h>
#endif#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/listener.h>
#include <event2/util.h>
#include <event2/event.h>
#include"qdebug.h"static const char MESSAGE[] = "Hello, World!\n";static const unsigned short PORT = 9995;static void listener_cb(struct evconnlistener *, evutil_socket_t,struct sockaddr *, int socklen, void *);
static void conn_writecb(struct bufferevent *, void *);
static void conn_eventcb(struct bufferevent *, short, void *);
static void signal_cb(evutil_socket_t, short, void *);int main3()
{struct event_base *base;struct evconnlistener *listener;struct event *signal_event;struct sockaddr_in sin = {0};base = event_base_new();//初始化if (!base) {fprintf(stderr, "Could not initialize libevent!\n");return 1;}sin.sin_family = AF_INET;sin.sin_port = htons(PORT);listener = evconnlistener_new_bind(base, listener_cb, (void *)base,LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1,(struct sockaddr*)&sin,sizeof(sin));//事件监听if (!listener) {fprintf(stderr, "Could not create a listener!\n");return 1;}signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);//信号事件if (!signal_event || event_add(signal_event, NULL)<0) {fprintf(stderr, "Could not create/add a signal event!\n");return 1;}event_base_dispatch(base);//启动evconnlistener_free(listener);event_free(signal_event);event_base_free(base);printf("done\n");return 0;
}static void
listener_cb(struct evconnlistener *listener, evutil_socket_t fd,struct sockaddr *sa, int socklen, void *user_data)
{struct event_base *base = static_cast<event_base*>(user_data);struct bufferevent *bev;bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);if (!bev) {fprintf(stderr, "Error constructing bufferevent!");event_base_loopbreak(base);return;}bufferevent_setcb(bev, NULL, conn_writecb, conn_eventcb, NULL);bufferevent_enable(bev, EV_WRITE);bufferevent_disable(bev, EV_READ);bufferevent_write(bev, MESSAGE, strlen(MESSAGE));
}static void
conn_writecb(struct bufferevent *bev, void *user_data)
{struct evbuffer *output = bufferevent_get_output(bev);if (evbuffer_get_length(output) == 0) {printf("flushed answer\n");bufferevent_free(bev);}
}static void
conn_eventcb(struct bufferevent *bev, short events, void *user_data)
{if (events & BEV_EVENT_EOF) {printf("Connection closed.\n");} else if (events & BEV_EVENT_ERROR) {printf("Got an error on the connection: %s\n",strerror(errno));/*XXX win32*/}/* None of the other events can happen here, since we haven't enabled* timeouts */bufferevent_free(bev);
}static void
signal_cb(evutil_socket_t sig, short events, void *user_data)
{struct event_base *base = static_cast<event_base*>(user_data);struct timeval delay = { 2, 0 };printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");event_base_loopexit(base, &delay);
}
libeventuse::libeventuse()
{main3();
}

下面是mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "ui_form.h"
#include"QString"
#include"qdebug.h"
#include"qmessagebox.h"
#include"libeventuse.h"#include <QMutex>
#include <QTime>
#include <QWidget>WorkThread::WorkThread(QObject *parent) : QThread(parent) {}void WorkThread::run() {  // 必须实现 run()
libeventuse tmp;
emit this->server_finish();
}MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);login_win=new Form;workthread=new WorkThread;login_win->hide();//登录窗口打开workthread->start();connect(this->workthread,&WorkThread::server_finish,[=](){qDebug()<<"服务器关闭";});connect(this->workthread,&WorkThread::finished,this->workthread,&QObject::deleteLater);connect(this->login_win,&Form::back,[=](){//槽函数this->show();//返回登录界面this->login_win->hide();//主执行界面关闭});}MainWindow::~MainWindow()
{delete login_win;delete ui;
}Form::Form(QWidget *parent) :QWidget(parent),ui(new Ui::Form)
{ui->setupUi(this);}Form::~Form()
{delete ui;
}void MainWindow::on_pushButton_clicked()
{QString RootName=ui->rootName->text();QString Password=ui->password->text();if(RootName.size()==0){QMessageBox::information(this, tr("提示"), tr("用户名没有输入"));return ;}else if(RootName.size()==0){QMessageBox::information(this, tr("提示"), tr("密码没有输入"));}if(RootName=="i"&&Password=="1")//验证用户和密码{qDebug()<<RootName<<Password;login_win->show();//主执行界面打开this->hide();//登录界面关闭}else{QMessageBox::information(this, tr("提示"), tr("用户或密码输入错误"));}}void Form::on_pushButton_clicked()
{emit this->back();//发送信号
}void MainWindow::on_pushButton_2_clicked()
{}

下面是libeventuse.h

#ifndef LIBEVENTUSE_H
#define LIBEVENTUSE_H
class libeventuse
{
public:libeventuse();
};#endif // LIBEVENTUSE_H

下面是mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
namespace Ui {
class Form;
}class Form : public QWidget
{Q_OBJECTpublic:explicit Form(QWidget *parent = 0);~Form();private slots:void on_pushButton_clicked();
signals:void back();
private:Ui::Form *ui;
};#include <QThread>
class WorkThread : public QThread {Q_OBJECT  // 必须添加!!!
public:explicit WorkThread(QObject *parent = nullptr);
protected:void run() override;  // 虚函数声明
signals:
void WorkThread_signal(int b);//自定义的信号
void server_finish();
};namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();Form* login_win=nullptr;WorkThread*workthread=nullptr;
private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();private:Ui::MainWindow *ui;
};#endif // MAINWINDOW_H

pro文件的配置
在这里插入图片描述

演示视频

20250415_153450

我视频第一部分展示了如何在qt创建窗口
视频第二部分展示了客户端连接到服务器后会接收到hello world
视频等审核过了我再放上来
审核没过我就发效果图
在这里插入图片描述

qt的一些知识

在这里插入图片描述
1.信号的格式
signals:
void WorkThread_signal(int b);//自定义的信号
2.注意事项,需要分写入Q_OBJECT才能这么定义
3.信号发送使用 emit 发送
在这里插入图片描述
4.使用connect槽函数来绑定信号要处理的逻辑
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/76954.shtml

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

相关文章

八、自动化函数

1.元素的定位 web自动化测试的操作核心是能够找到页面对应的元素&#xff0c;然后才能对元素进行具体的操作。 常见的元素定位方式非常多&#xff0c;如id,classname,tagname,xpath,cssSelector 常用的主要由cssSelector和xpath 1.1 cssSelector选择器 选择器的功能&#x…

Web三漏洞学习(其二:sql注入)

靶场&#xff1a;NSSCTF 、云曦历年考核题 二、sql注入 NSSCTF 【SWPUCTF 2021 新生赛】easy_sql 这题虽然之前做过&#xff0c;但为了学习sql&#xff0c;整理一下就再写一次 打开以后是杰哥的界面 注意到html网页标题的名称是 “参数是wllm” 那就传参数值试一试 首先判…

单片机非耦合业务逻辑框架

在小型单片机项目开发初期&#xff0c;由于业务逻辑相对简单&#xff0c;我们往往较少关注程序架构层面的设计。 然而随着项目经验的积累&#xff0c;开发者会逐渐意识到模块间的耦合问题&#xff1a;当功能迭代时&#xff0c;一处修改可能引发连锁反应。 此时&#xff0c;构…

Zookeeper三台服务器三节点集群部署(docker-compose方式)

1. 准备工作 - 服务器:3 台服务器,IP 地址分别为 `10.10.10.11`、`10.10.10.12`、`10.10.10.13`。 - 安装 Docker:确保每台服务器已安装 Docker 和 Docker Compose。 - 网络通信:确保三台服务器之间可以通过 IP 地址互相访问,并开放以下端口: - `2181`:Zookeeper 客户…

Mac关闭sip方法

Mac关闭sip方法 导航 文章目录 Mac关闭sip方法导航完整操作流程图详细步骤 完整操作流程图 这东西是我在网上搬运下来的&#xff0c;但是我在为业务实操过程中&#xff0c;根据实操情况还是有新的注意点的 详细步骤 1.在「关于本机」-「系统报告」-「软件」;查看SIP是否开启…

C++| 深入剖析std::list底层实现:链表结构与内存管理机制

引言 std::list的底层实现基于双向链表&#xff0c;其设计哲学与std::vector截然不同。本文将深入探讨其节点结构、内存分配策略及迭代器实现原理&#xff0c;揭示链表的性能优势和潜在代价。 1. 底层数据结构&#xff1a;双向链表 每个std::list节点包含&#xff1a; 数据域…

汉诺塔问题——用贪心算法解决

目录 一&#xff1a;起源 二&#xff1a;问题描述 三&#xff1a;规律 三&#xff1a;解决方案 递归算法 四&#xff1a;代码实现 复杂度分析 一&#xff1a;起源 汉诺塔&#xff08;Tower of Hanoi&#xff09;问题起源于一个印度的古老传说。在世界中心贝拿勒斯&#…

【Python】Python 100题 分类入门练习题 - 新手友好

Python 100题 分类入门练习题 - 新手友好篇 - 整合篇 一、数学问题题目1&#xff1a;组合数字题目2&#xff1a;利润计算题目3&#xff1a;完全平方数题目4&#xff1a;日期天数计算题目11&#xff1a;兔子繁殖问题题目18&#xff1a;数列求和题目19&#xff1a;完数判断题目21…

【linux】--- 进程概念

进程概念 1.认识冯诺依曼结构2. 操作系统&#xff08;Operator system)2.1 概念2.2 设计OS的目的2.3 理解操作系统2.4 如何理解管理2.5 理解系统调用和库函数 3. 进程3.1 基本概念和基本操作3.1.1 描述进程 - PCB3.1.2 task_struct3.1.3 查看进程 3.2 进程状态3.2.1 运行&&…

算法堆排序记录

【算法】排序算法之堆排序 - 知乎 应用场景&#xff1a;获取第n个大或者小的数 操作步骤&#xff1a; 1、将数组构造成堆 2、调整根节点为最大堆 ->倒序对每个根节点执行最大化 ->根节点最大化过程中如果发生交换&#xff0c;需要保证子节点也为最大堆&#xff08;执行…

STM32 模块化开发实战指南:系列介绍

本文是《STM32 模块化开发实战指南》系列的导读篇,旨在介绍整个系列的写作目的、适用读者、技术路径和每一篇的主题规划。适合从事 STM32、裸机或 RTOS 嵌入式开发的个人开发者、初创工程师或企业项目团队。 为什么要写这个系列? 在嵌入式开发中,很多人刚开始都是从点亮一个…

【眼底辅助诊断开放平台】项目笔记

这是一个标题 任务一前端页面开发&#xff1a;后端接口配置&#xff1a; 任务二自行部署接入服务 日志修改样式和解析MD文档接入服务 Note前端登陆不进去/更改后端api接口304 Not Modifiedlogin.cache.jsonERR_CONNECTION_TIMED_OUT跨域一般提交格式proxy.ts src/coponents 目录…

【后端开发】Spring MVC-计算器、用户登录、留言板

文章目录 前后端分离设计接口设计思路项目问题解决思路 计算器需求分析接口定义前端页面代码服务器代码 用户登录需求分析接口定义用户登录校验接口查询登录用户接口 前端页面代码用户登录校验查询登录用户 服务器代码前后端交互 留言版需求分析接口定义获取全部留言发布留言前…

在Ubuntu-22.04.5中安装ONLYOFFICE DocSpace(协作空间)【注意:安装失败,谨慎参考!】

1. 通过Docker安装 预计需要下载10G的镜像。 &#xff08;1&#xff09;下载docspace安装脚本 curl -fsSL https://download.onlyoffice.com/docspace/docspace-install.sh -o docspace-install.sh &#xff08;2&#xff09;修改docker compose的别名为docker-compose ali…

2025年计算机领域重大技术突破与行业动态综述

——前沿技术重塑未来&#xff0c;开发者如何把握机遇&#xff1f; 2025年第一季度&#xff0c;全球计算机领域迎来多项里程碑式进展&#xff0c;从量子计算到人工智能&#xff0c;从芯片设计到网络安全&#xff0c;技术革新与产业融合持续加速。本文梳理近三个月内最具影响力…

一、LLM 大语言模型初窥:起源、概念与核心原理

一、初识大模型 1.1 人工智能演进与大模型兴起:从A11.0到A12.0的变迁 AI 1.0时代&#xff08;2012-2022年&#xff09; 感知智能的突破&#xff1a;以卷积神经网络&#xff08;CNN&#xff09;为核心&#xff0c;AI在图像识别、语音处理等感知任务中超越人类水平。例如&#…

Redis 分布式锁+秒杀异步优化

文章目录 问题思路setnx实现锁误删问题和解决方案Redis Lua脚本问题引出解决方案 setnx实现的问题Redission快速入门redission可重入锁原理 秒杀优化(异步优化)异步秒杀思路秒杀资格判断Redis消息队列 问题 比如我们两个机器都部署了我们项目&#xff0c;这里nginx使用轮询的方…

机器学习中的距离度量与优化方法:从曼哈顿距离到梯度下降

目录 前言一、曼哈顿距离(Manhattan Distance)&#xff1a;二、切比雪夫距离 (Chebyshev Distance)&#xff1a;三、 闵可夫斯基距离(Minkowski Distance)&#xff1a;小结四、余弦距离(Cosine Distance)五、杰卡德距离(Jaccard Distance)六、交叉验证方法6.1 HoldOut Cross-v…

HTML 嵌入标签对比:小众(<embed>、<object>) 与 <iframe> 的优缺点及使用场景和方式

需求背景 在网页开发中&#xff0c;嵌入外部资源预览&#xff08;如视频、PDF、地图或其他网页&#xff09;是常见的需求。HTML 提供了多种标签来实现这一功能&#xff0c;其中 <embed>、<object> 和 <iframe> 是最常用的三种。本文将对比它们的优缺点&…

未来七轴机器人会占据主流?深度解析具身智能方向当前六轴机器人和七轴机器人的区别,七轴力控机器人发展会加快吗?

六轴机器人和七轴机器人在设计、功能和应用场景上存在明显区别。六轴机器人是工业机器人的传统架构&#xff0c;而七轴机器人则在多自由度和灵活性方面进行了增强。 本文将在理解这两者的区别以及为何六轴机器人仍然是市场主流&#xff0c;从多个方面进行深入解读六轴和七轴区…