【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.rhkb.cn/news/316670.html

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

相关文章

代码随想录算法训练营第二十六天||39. 组合总和、40.组合总和II、131.分割回文串

文章目录 一、39. 组合总和 思路 二、40.组合总和II 思路 三、131.分割回文串 思路 一、39. 组合总和 给定一个无重复元素的数组 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的数字可以无限制重复被选取…

Vitis HLS 学习笔记--HLS入门示例集合-目录

目录 1. 示例集合概述 2. Interface 接口 2.1 Aggregation_Disaggregation 2.1.1 aggregation_of_m_axi_ports 2.1.2 aggregation_of_nested_structs 2.1.3 aggregation_of_struct 2.1.4 auto_disaggregation_of_struct 2.1.5 disaggregation_of_axis_port 2.1.6 stru…

Liunx磁盘管理(上)

一.硬盘类型 机械硬盘&#xff08;HDD&#xff09; 机械硬盘&#xff08;HDD&#xff09;是一种存储设备&#xff0c;使用旋转磁盘和读/写磁头来存储和检索数据。以下是机械硬盘的基本结构&#xff1a; 盘片&#xff08;Platters&#xff09;&#xff1a;机械硬盘通常由多个盘…

element的el-table 解决表格多页选择数据时,数据被清空

问题&#xff1a;切换页码时&#xff0c;勾选的数据会被清空 重点看我圈出来的&#xff0c;直接复制&#xff0c;注意&#xff0c;我这里 return row.productId;一般大家的是 return row.id,根据接口定的唯一变量 :row-key"getRowKeys"​​​​​​​:reserve-sele…

基于STM32和阿里云的智能台灯(STM32+ESP8266+MQTT+阿里云+语音模块)

一、主要完成功能 1、冷光模式和暖光模式两种灯光 主要支持冷光和暖光模式两种&#xff0c;可以通过语音模块或手机app远程切换冷暖光 2、自动模式和手动模式 主要支持手动模式和自动两种模式&#xff08;app或语音助手切换&#xff09; (1)自动模式&#xff1a;根据环境光照…

通信原理(2)--随机过程

通信原理(2)–随机过程 3.1随机过程的基本概念 随机过程{x(t)}由一族时间函数 x i ( t ) x_i(t) xi​(t)&#xff0c;i1,2.3…组成&#xff0c;每一个时间函数 x i ( t ) x_i(t) xi​(t)称为随机过程{x(t)}的一个样本函数&#xff08;一个实现&#xff09; 每个样本函数在时间…

http1.1和http2.0的同源请求数限制

判断协议版本 :scheme: 在请求头中表示使用的是HTTP/2协议。即 出现 :开头的请求头Chrome 只支持查看 HTTP/1.x 的 Raw Headers&#xff0c;对这种请求&#xff0c;会给出 view source 选项。HTTP2.0不给出。可继续学习 https://www.cnblogs.com/kirito-c/p/10360868.html抓包…

笔记:编写程序,分别采用面向对象和 pyplot 快捷函数的方式绘制正弦曲线 和余弦曲线。 提示:使用 sin()或 cos()函数生成正弦值或余弦值。

文章目录 前言一、面向对象和 pyplot 快捷函数的方式是什么&#xff1f;二、编写代码面向对象的方法&#xff1a;使用 pyplot 快捷函数的方法&#xff1a; 总结 前言 本文将探讨如何使用编程语言编写程序&#xff0c;通过两种不同的方法绘制正弦曲线和余弦曲线。我们将分别采用…

DSP开发实战教程--EPWM模块的影子寄存器详细讲解原理和代码实例

EPWM模块影子寄存器的原理 在TI&#xff08;Texas Instruments&#xff09;的DSP28335中&#xff0c;EPWM&#xff08;Enhanced Pulse Width Modulator&#xff09;模块提供了高精度、高灵活性的PWM信号生成功能。为了能在不影响当前PWM波形输出的情况下预装载新的PWM参数&…

cocos-lua资源管理

本文介绍cocos-lua项目的资源管理和工作流&#xff0c;适用人群包括初学者和有经验开发者&#xff0c;故读者可根据自己的需要有选择性的查阅自己需要的内容&#xff0c;下文以ccs代指Cocos Studio 一.简单案例解析 下文通过介绍一个简单demo&#xff0c;介绍合图和资源目录结…

[C++][算法基础]最大不相交区间数量(贪心 + 区间问题2)

给定 &#x1d441; 个闭区间 [&#x1d44e;&#x1d456;,&#x1d44f;&#x1d456;]&#xff0c;请你在数轴上选择若干区间&#xff0c;使得选中的区间之间互不相交&#xff08;包括端点&#xff09;。 输出可选取区间的最大数量。 输入格式 第一行包含整数 &#x1d4…

【算法基础实验】图论-UnionFind连通性检测之quick-union

Union-Find连通性检测之quick-union 理论基础 在图论和计算机科学中&#xff0c;Union-Find 或并查集是一种用于处理一组元素分成的多个不相交集合&#xff08;即连通分量&#xff09;的情况&#xff0c;并能快速回答这组元素中任意两个元素是否在同一集合中的问题。Union-Fi…

PHP源码_最新在线工具箱网站系统源码

项目运行截图 源码贡献 https://githubs.xyz/boot?app41 部分数据库表 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;-- ---------------------------- -- Table structure for toolbox_category -- ---------------------------- DROP TABLE IF EXISTS toolbox_category…

StarRocks x Paimon 构建极速实时湖仓分析架构实践

Paimon 介绍 Apache Paimon 是新一代的湖格式&#xff0c;可以使用 Flink 和 Spark 构建实时 Lakehouse 架构&#xff0c;以进行流式处理和批处理操作。Paimon 创新性地使用 LSM&#xff08;日志结构合并树&#xff09;结构&#xff0c;将实时流式更新引入 Lakehouse 架构中。 …

医学vr虚拟仿真综合实验教学平台为科研教学提供了坚实的基础

在兽医专业的广袤领域中&#xff0c;动物解剖学作为基石学科&#xff0c;为组织胚胎学、生理学、病理解剖学、外科手术学、临床诊断学等科研教学提供了坚实的基础。而如今&#xff0c;随着科技的飞速发展&#xff0c;我们迎来了一个全新的学习时代——3D数字动物解刨虚拟仿真实…

[iOS]使用CocoaPods发布公开库

1.检查库名是否已被占用 选择库名时&#xff0c;尽量选择具有描述性并且独特的名字&#xff0c;这不仅可以避免命名冲突&#xff0c;还可以帮助用户更好地理解库的用途和功能。 在实际创建和发布 CocoaPods 库之前&#xff0c;确实应该检查库名是否已经被占用&#xff0c;以避…

AutoCAD 2025 for mac/win:设计未来,触手可及

在数字化时代&#xff0c;设计不再局限于纸笔之间&#xff0c;而是跃然于屏幕之上&#xff0c;AutoCAD 2025正是这一变革的杰出代表。无论是Mac用户还是Windows用户&#xff0c;AutoCAD 2025都以其卓越的性能和出色的用户体验&#xff0c;成为了CAD设计绘图领域的佼佼者。 Aut…

Vuforia AR篇(三)— AR模型出场效果

目录 前言一、AR模型出场二、AR出场特效三、添加过渡效果四、效果 前言 在这个数字化日益增长的时代&#xff0c;增强现实&#xff08;AR&#xff09;技术正以前所未有的速度发展。AR模型&#xff0c;作为这一技术的核心组成部分&#xff0c;不仅改变了我们与数字世界的互动方…

【MATLAB源码-第201期】基于matlab的黏菌群优化算法(SMA)无人机三维路径规划,输出做短路径图和适应度曲线

操作环境&#xff1a; MATLAB 2022a 1、算法描述 黏菌优化算法&#xff08;Slime Mould Algorithm, SMA&#xff09;是一种新颖的启发式优化方法&#xff0c;其灵感来源于自然界中的真菌——黏菌。这种算法模拟了黏菌在寻找食物时的行为和网络形成策略。在本文中&#xff0c…

Python | Leetcode Python题解之第58题最后一个单词的长度

题目&#xff1a; 题解&#xff1a; class Solution:def lengthOfLastWord(self, s: str) -> int:ls[]for i in s.split():ls.append(i)return len(ls[-1])