【QT进阶】Qt http编程之实现websocket server服务器端

往期回顾

【QT进阶】Qt http编程之json解析的简单介绍-CSDN博客

【QT进阶】Qt http编程之nlohmann json库使用的简单介绍-CSDN博客

【QT进阶】Qt http编程之websocket的简单介绍-CSDN博客

 【QT进阶】Qt http编程之实现websocket server服务器端

一、最终效果

通过ip地址和端口号,我可以开启服务去连接客户端并发送消息

 二、套接字(补充一个知识点)

1、什么是套接字

套接字(Socket)是在计算机网络编程中用于实现网络通信的一种机制。它是网络通信的端点,可以用于在不同计算机之间或同一台计算机的不同进程之间进行数据传输。通过套接字编程,程序可以实现各种网络应用,实现计算机之间的数据交换和通信。

2、套接字类型

流套接字(StreamSocket):

基于TCP协议的套接字类型,提供面向连接的、可靠的、双向的数据流传输。适用于需要可靠传输和顺序数据传输的场景,如HTTP、FTP等应用。

数据报套接字(DatagramSocket):

基于UDP协议的套接字类型,提供无连接、不可靠的数据报传输。适用于需要快速传输但不需要可靠性的场景,如DNS、实时视频传输等。

3、套接字通信过程: 

创建套接字:在应用程序中创建套接字对象,指定协议类型、地址族等参数。
绑定套接字:将套接字绑定到一个特定的IP地址和端口号,以便其他计算机或进程可以通过该地址与之通信。
监听连接:对于服务器端套接字,调用listen()函数开始监听客户端连接请求。
接受连接:对于服务器端套接字,调用accept()函数接受客户端的连接请求,返回一个新的套接字用于与客户端通信。
建立连接:对于客户端套接字,调用connect()函数向服务器发起连接请求,建立与服务器的连接。
数据传输:通过套接字的读写操作(如send()、recv())进行数据传输,实现通信功能。
关闭套接字:通信结束后,调用close()或类似函数关闭套接字,释放资源。

4、套接字编程: 

在网络编程中,套接字通常由操作系统提供的网络库(如Socket API)来实现。

套接字编程可以使用不同的编程语言和平台实现,如C/C++、Python、Java等。

我们可以通过套接字编程实现各种网络通信应用,包括客户端-服务器模型、P2P通信、实时数据传输等。

三、基于Qt框架实现WebSocket服务器应用

在vs2019里创建,记得先包含QT模块:websockets,

右键单击项目->属性->Qt Project Settings->QT Moduls->选择websockets

1、主要功能实现

(1)通过Qt的QWebSocketServer类实现WebSocket服务器,用于处理客户端的连接和消息通信。

(2)可以开启、关闭服务器,监听指定的IP地址和端口,处理新的客户端连接,以及处理客户端断开连接事件。

(3)可以接收客户端发送的消息,并实现消息的转发功能。

2、整体思路:

2.1开启服务器

用户通过界面输入IP地址和端口号来开启WebSocket服务器。

WebsocketServerDemo::WebsocketServerDemo(QWidget *parent): QWidget(parent)
{ui.setupUi(this);this->setWindowTitle(u8"Websocket Server");this->resize(1000, 600);ui.lineEdit_IP->setText("192.168.0.109"); //IP地址输入框ui.lineEdit_Port->setText("8000");//端口号输入框//创建websocketServer,用于处理WebSocket连接。m_WebSocketServer = new QWebSocketServer(u8"server", QWebSocketServer::NonSecureMode);
}
2.2保存客户端信息

当有新的客户端连接时,将其添加到m_clients列表中,并保存对应的URL和套接字到mapSocket映射中,方便后续管理。 

//处理新的链接,保存连接并更新在线用户列表。
void WebsocketServerDemo::onNewConnection()
{//使用nextPendingConnection方法获取下一个挂起的连接//返回一个QWebSocket指针pSocket,表示新连接的套接字pSocket = m_WebSocketServer->nextPendingConnection();//将新连接pSocket添加到m_clients列表中,用于跟踪所有客户端连接。m_clients << pSocket;//每个client上线时,链接他的textMessageReceived信号,处理接受的消息connect(pSocket, SIGNAL(textMessageReceived(QString)), this, SLOT(processTextMessage(QString)));//用户掉线处理connect(pSocket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));//如何知道是哪个client发送的消息//获取客户端连接的URL,用于标识客户端。QString peerName = pSocket->requestUrl().toString();cout << "peerName = " << peerName.toStdString() << endl;//将客户端连接的URL和pSocket套接字保存到mapSocket映射中,用于后续管理和查找客户端连接。mapSocket[peerName] = pSocket;//将客户端连接的URL添加到在线用户列表listWidget_OnlineUser中,显示在线用户。ui.listWidget_OnlineUser->addItem(peerName);
}
2.3连接槽函数

每个客户端连接都会关联处理消息接收和断开连接的槽函数。

    //每个client上线时,链接他的textMessageReceived信号,处理接受的消息connect(pSocket, SIGNAL(textMessageReceived(QString)), this, SLOT(processTextMessage(QString)));//用户掉线处理connect(pSocket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
2.4显示消息信息

在处理消息时,会显示时间、客户端信息和消息内容,并实现消息转发的功能。 

//处理接收到的消息,显示在文本框中并处理消息转发。
void WebsocketServerDemo::processTextMessage(QString message) 
{QString time = current_date_time->currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz ddd");QString item = pSocket->requestUrl().toString();ui.textEdit_RecvMsg->append(time + "" + item + "\n" + message);//处理消息转发//...}
2.5客户端断开连接时的处理

当客户端断开连接时,会从列表、映射中移除对应关系,并更新界面显示。 

//客户端连接断开的操作,从在线用户列表中移除断开的客户端。
//处理客户端断开连接时的清理工作,包括从列表中移除客户端连接、从映射中移除对应关系,并更新界面显示。
void WebsocketServerDemo::socketDisconnected() 
{//智能索引遍历存储客户端连接的m_clients列表中的每个QWebSocket套接字skfor (auto sk : m_clients){if (!sk->isValid())//检查当前套接字sk是否有效,即客户端是否已断开连接{QString temp_key; //用于暂时存储要删除的客户端连接的URL。ui.textEdit_RecvMsg->append("map size = " + QString(mapSocket.size()) + "\n");//显示当前mapSocket映射的大小。//遍历mapSocket映射,查找与当前客户端套接字sk对应的URLfor (auto it = mapSocket.begin(); it!=mapSocket.end(); it++){if (it.value() == sk){//删除该客户端连接的相关信息://通过URL在在线用户列表中找到对应项,并删除。QList<QListWidgetItem*> list;list = ui.listWidget_OnlineUser-> findItems(it.key(), Qt::MatchCaseSensitive);//从映射中移除该URL对应的套接字。QListWidgetItem* sel = list[0];int r = ui.listWidget_OnlineUser->row(sel);QListWidgetItem* item = ui.listWidget_OnlineUser->takeItem(r);ui.listWidget_OnlineUser->removeItemWidget(item);delete item;//从m_clients列表中移除当前客户端套接字sk。m_clients.removeOne(sk);QString time = current_date_time->currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz ddd");ui.textEdit_RecvMsg->append(time + "" + it.key() + "下线了\n");///将当前URL存储在temp_key中,用于后续删除操作。temp_key = it.key();}}//从mapSocket映射中移除存储在temp_key中的URL并显示移除后的mapSocket大小mapSocket.remove(temp_key);ui.textEdit_RecvMsg->append("after remove, map size = " + QString(mapSocket.size()) + "\n");}}
}

3、类结构分析

 WebsocketServerDemo类是主要的应用类,继承自QWidget,负责处理界面相关的操作和WebSocket服务器的管理。

在构造函数中初始化界面和WebSocket服务器对象。

在析构函数中关闭WebSocket服务器。

包含槽函数:

on_btnOpenServer_clicked()用于开启服务器,
on_btnCloseServer_clicked()用于关闭服务器,
onNewConnection()处理新的连接,
processTextMessage()处理接收到的消息,
socketDisconnected()处理客户端断开连接,
on_btnSend_clicked()用于向所有客户端发送消息。


以上就是Qt里实现websocket server服务器端的简单介绍。

都看到这里了,点个赞再走呗朋友~

加油吧,预祝大家变得更强!

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

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

相关文章

人工智能时代的关键技术:深入探索向量数据库及其在AI中的应用

文章目录 1. 理解向量数据库&#xff1a;二维模型示例2. 向量数据库中的数据存储与检索3. 向量数据库如何工作&#xff1f;4. 向量数据库如何知道哪些向量相似&#xff1f; 在人工智能技术日益成熟的当下&#xff0c;向量数据库作为处理和检索高维数据的关键工具&#xff0c;对…

【治理与监管题】

https://www.pcisecuritystandards.org/ https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-88r1.pdf 介绍 网络安全是一个快速发展的环境&#xff0c;恶意行为者不遗余力地利用高度敏感系统中的漏洞&#xff0c;通常旨在造成敏感企业数据的严重破坏、破坏和…

Dropout Feature Ranking for Deep Learning Models

摘要 深度神经网络( deep neural networks&#xff0c;DNNs )在多个领域取得了最新的研究成果。不幸的是&#xff0c;DNNs因其不可解释性而臭名昭著&#xff0c;从而限制了其在生物和医疗保健等假说驱动领域的适用性。此外&#xff0c;在资源受限的环境下&#xff0c;设计依赖…

StorCli工具学习记录

StorCli工具学习记录 StorCLI&#xff08;Storage Command Line Interface&#xff09;是一款强大的命令行管理工具&#xff0c;用于管理和配置存储控制器。这一工具主要适用于Broadcom&#xff08;原LSI&#xff09;及Intel RAID控制器。 下面将详细介绍StorCLI的安装、特点、…

数据结构 - 顺序表实现通讯录

test.c文件 #define _CRT_SECURE_NO_WARNINGS 1#include "Contact.h" int main() {Con myContacts;ConInit(&myContacts);int choice;int index;char targetName[100];PerInfo contact; // 创建一个新的联系人信息实例while (1) {printf("\n--- 通讯录管理…

Linux下的UDEV机制/守护进程

一. Udev机制概念引入 ( 需要在 etc/udev/rules.d/ 下创建设备的相关规则&#xff0c;不然有可能udev机制生成的设备文件不具备可读可写的权限&#xff0c;adb无法成功通过该设备文件访问设备 ) a. 创建文件夹 sudo vim Xiaomi-audroid.rules b. 添加规则 …

景区ar导览实景导航小程序系统开发源码搭建

开发景区AR导览实景导航小程序系统需要以下步骤&#xff1a; 1. 确定需求和功能&#xff1a;根据景区AR导览实景导航的需求和功能&#xff0c;确定需要开发哪些功能模块&#xff0c;如AR实景导航、语音讲解、景点介绍、路线规划等。 2. 确定技术方案&#xff1a;选择适合的技…

在vscode上面进行分支merge的记录

前言&#xff1a;在我们的项目中&#xff0c;有两个分支&#xff1a;master和liutielong。现在要将liutielong分支的改动merge到master分支中。 如果master分支已经更改了&#xff0c;所以要先pull&#xff08;这是在git bash里面的命令&#xff09;。 git pull origin master…

5分钟——快速搭建后端springboot项目

5分钟——快速搭建后端springboot项目 1. idea新建工程2. 构建pom.xml文件3. 构建application.yml配置文件4. 构建springboot启动类5. 补充增删改查代码6. 运行代码 1. idea新建工程 点击右上角新建一个代码工程 别的地方不太一样也不用太担心&#xff0c;先创建一个工程就好…

学习配置文件

1.yml的语法格式问题&#xff1a; 2.配置文件获取数据&#xff1a; Value方式&#xff1a; Environment&#xff1a; 获取自定义对象的方式&#xff1a; 设置get和set方法&#xff0c;还有toString方法。 3. 日志配置&#xff1a; logo的配置&#xff1a; 日志插件&#xff…

汽车纵染压制专用液压机比例阀放大器

汽车纵染压制专用液压机比例阀放大器是一种专门用于汽车纵梁拉伸工艺的设备&#xff0c;它也可以用于其他金属薄板的压制成型及校正工艺。该类型的液压机通常具备独立的动力机构和电气系统&#xff0c;采用PLC技术进行控制&#xff0c;以确保操作的准确性和稳定性。除了纵梁拉伸…

【iOS】分类,扩展与关联对象

文章目录 前言一、分类实现原理二、分类加载流程三、扩展四、类别与类扩展的区别五、关联对象动态添加取值移除关联对象应用 总结 前言 上一篇章我们探究了类与对象的底层&#xff0c;这一篇我们探究一下分类&#xff0c;扩展与关联对象 一、分类实现原理 首先我们知道扩展是…

Rust :快速了解 VecDeque 双向队列

VecDeque是Rust标准库中的一个双端队列&#xff08;double-ended queue&#xff09;实现&#xff0c;它提供了在队列两端进行高效插入和删除操作的能力。双端队列是一种具有队列和栈的性质的数据结构&#xff0c;元素可以从两端弹出&#xff0c;其限定插入和删除操作在表的两端…

CentOS-7安装grafana

一、通用设置&#xff08;分别在4台虚拟机设置&#xff09; 1、配置主机名 hostnamectl set-hostname --static 主机名2、修改hosts文件 vim /etc/hosts 输入&#xff1a; 192.168.15.129 master 192.168.15.133 node1 192.168.15.134 node2 192.168.15.136 node33、 保持服…

GaussianEditor:快速可控的3D编辑与高斯飞溅

GaussianEditor: Swift and Controllable 3D Editing with Gaussian Splatting GaussianEditor&#xff1a;快速可控的3D编辑与高斯飞溅 Yiwen Chen*​1,2   Zilong Chen*​3,5   Chi Zhang2   Feng Wang3   Xiaofeng Yang2 陈怡雯 *​1,2 陈子龙 *​3,5 张驰 2 王峰 3 杨晓…

MySQL学习笔记7——视图和存储过程

视图和存储过程 一、视图1、视图的作用2、如何操作视图和视图中的数据3、视图的优缺点 二、存储过程1、如何创建存储过程2、调用存储过程3、修改和删除存储过程 一、视图 1、视图的作用 视图是一种虚拟表&#xff0c;我们可以把一段查询语句作为视图存储在数据库中&#xff0…

Cocos Creator 场景树与组件实例查找详解

前言 Cocos Creator 是一款由 Cocos-BCX 团队开发的一款基于 JavaScript 的游戏开发引擎&#xff0c;它提供了一套完整的游戏开发工具和资源&#xff0c;方便开发者快速构建游戏。在 Cocos Creator 中&#xff0c;场景树和组件实例的查找是非常重要的&#xff0c;它们可以帮助开…

.NET Core 中的 ORM 框架对比

在 .NET Core 中选择正确的对象关系映射 &#xff08;ORM&#xff09; 工具可能是开发生命周期中的关键决策。所选的 ORM 会影响应用程序的性能、可维护性和可伸缩性。在本文中&#xff0c;我们将深入分析三个突出的 ORM 选择&#xff1a;Entity Framework Core、Dapper 和 NHi…

算法设计与优化——向量中数据唯一化

0.概述 很多应用中&#xff0c;在进一步处理之前都要求数据元素互异。以网络搜索引擎为例&#xff0c;多个计算节点各自获得的局部搜索结果&#xff0c;需首先剔除其中重复的项目&#xff0c;方可合并为一份完整的报告。类似地&#xff0c;所谓向量的唯一化处理&#xff0c;就…

liqo学习及安装,k8s,kubernetes多集群互联

先按照官方的教程在虚拟机安装学习 在开始以下教程之前&#xff0c;您应该确保您的系统上安装了以下软件&#xff1a; Docker&#xff0c;容器运行时。Kubectl&#xff0c;Kubernetes 的命令行工具。 curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.…