Qt学习笔记(三)网络编程

系列文章目录

Qt开发笔记(一)Qt的基础知识及环境编译(泰山派)
Qt学习笔记(二)Qt 信号与槽
Qt学习笔记(三)网络编程


文章目录

  • 系列文章目录
  • 前言
  • 一、Qt网络模块
  • 二、TCP网络的编写
    • 2.1 服务端
      • 2.1.1 编写思路
      • 2.1.2 实现代码
    • 2.2 客户端
      • 2.2.1 编写思路
      • 2.2.2 实现代码
  • 三、 浅谈MQTT
    •   常见的MQTT报文有以下15种,其中可以分为三大类:**连接、发布和订阅**,对应MQTT的实现流程。而一个**MQTT数据包由固定头(Fixed header)、可变头(Variable header)、消息体(payload)三部分构成**。 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/70716e1d80094d73a1c8ad57606ef727.png)   知道以上这部分其实就差不多了,毕竟我们不是专业搞信息工程或者网络专业的,剩下的很琐碎的东西学起来就很费时费力了。


前言

  之前我们在Linux应用层的学习时提到了网络编程,本节是进行Qt下TCP / IP 客户端的编写。


一、Qt网络模块

  Qt 网络模块为我们提供了编写 TCP / IP 客户端和服务器的类。它提供了较低级别的类,例如代表低级网络概念的 QTcpSocket,QTcpServer 和QUdpSocket,以及诸如 QNetworkRequest,QNetworkReply 和QNetworkAccessManager 之类的高级类来执行使用通用协议的网络操作。它还提供了诸如QNetworkConfiguration,QNetworkConfigurationManager,QNetworkSession等类,实现承载管理。
在这里插入图片描述

二、TCP网络的编写

2.1 服务端

  所谓服务端就是指通过监听某个端口指令来判断是否有客户端连接,如果有则建立新的socket,之后客户端负责输入ip和port就可以完成连接了。在QT中,socket被视为输入输出流,数据的收发是通过read()和write()来实现。
在这里插入图片描述

2.1.1 编写思路

 1. 创建QTcpServer服务端对象
  这部分就是简单的对象实例化和槽函数的链接。
 2. 开始/停止监听
  在这个过程中最主要的是listen()函数,它可以设置监听的IP地址和端口,一般一个服务器端程序只监听某个端口的网络连接。

//   函数返回 true 时,表示监听成功
bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)

 3. 动态创建QTcpSocket对象
   这里主要利用nextPendingConnection()函数,它用于有新的客户端接入时,创建一个与客户端连接的QTcpSocket对象,然后发射 newConnection() 信号,通常我们在槽函数中使用它来进行新链接的创建。
 4. 接受消息并处理或者判断连接状态并连接\断开
   这里就很简单,可以创建类似用下文的receiveMessege_Slot()进行数据处理,或者是错误码检测之类的。

2.1.2 实现代码

   记得编译前,在.pro文件中修改 QT += network ,这里注意下。

// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QtMqtt/qmqttclient.h>
#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();signals:private slots:void netConnect_Slot(void);void receiveMessege_Slot(void);void disConnect_Slot(void);private:Ui::MainWindow *ui;QTcpServer *m_server;QList<QTcpSocket*> m_clients;
};
#endif // MAINWINDOW_H// mainwindow.c
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);m_server = new QTcpServer(this);connect(m_server, SIGNAL(newConnection()), this, SLOT(netConnect_Slot()));if (!m_server->listen(QHostAddress::Any, 1883)) {qDebug() << "Failed to Connect!";} else {qDebug() << "Succeed to Connect!";}
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::netConnect_Slot()
{QTcpSocket *m_socket = m_server->nextPendingConnection();connect(m_socket, SIGNAL(readyRead()), this, SLOT(receiveMessege_Slot()));connect(m_socket, SIGNAL(disconnected()), this, SLOT(disConnect_Slot()));m_clients.append(m_socket);qDebug() << "New client connected";
}void MainWindow::receiveMessege_Slot()
{QTcpSocket *m_socket = qobject_cast<QTcpSocket *>(sender());if (m_socket) {QByteArray requestData = m_socket->readAll();qDebug() << "Received MQTT message:" << requestData;}
}void MainWindow::disConnect_Slot()
{QTcpSocket *m_socket = qobject_cast<QTcpSocket *>(sender());if (m_socket) {m_clients.removeOne(m_socket);m_socket->deleteLater();qDebug() << "Client disconnected";}
}

2.2 客户端

   这部分的内容十分重要,涉及到我们后期使用mqtt协议,通常情况下我们不主动搭建服务器,仅调用客户端就满足对“上云”的要求了。

2.2.1 编写思路

 1. QTcpSocket 实例化并与信号和槽连接
 2. 连接到服务器(指定的 IP 和端口)
  这里主要是利用tcpSocket->connectToHost("服务器地址", 端口号);进行连接,注意和上面的listen区分一下。
 3. 消息通过 TCP 套接字发送到服务器
  利用write和readAll即可完成数据的读写。

2.2.2 实现代码

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QTcpSocket>
#include <QTextEdit>
#include <QLineEdit>
#include <QPushButton>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void onConnectButtonClicked();void onSendButtonClicked();void onReadyRead();void onError(QAbstractSocket::SocketError socketError);private:Ui::MainWindow *ui;QTcpSocket *tcpSocket;QTextEdit *logTextEdit;QLineEdit *messageLineEdit;QPushButton *connectButton;QPushButton *sendButton;
};#endif // MAINWINDOW_H#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMessageBox>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow),tcpSocket(new QTcpSocket(this))
{ui->setupUi(this);// 获取控件logTextEdit = findChild<QTextEdit*>("logTextEdit");messageLineEdit = findChild<QLineEdit*>("messageLineEdit");connectButton = findChild<QPushButton*>("connectButton");sendButton = findChild<QPushButton*>("sendButton");// 连接信号和槽connect(connectButton, &QPushButton::clicked, this, &MainWindow::onConnectButtonClicked);connect(sendButton, &QPushButton::clicked, this, &MainWindow::onSendButtonClicked);connect(tcpSocket, &QTcpSocket::readyRead, this, &MainWindow::onReadyRead);connect(tcpSocket, &QTcpSocket::errorOccurred, this, &MainWindow::onError);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::onConnectButtonClicked()
{// 连接到服务器tcpSocket->connectToHost("127.0.0.1", 1234);if (!tcpSocket->waitForConnected(3000)) {QMessageBox::critical(this, "错误", "连接服务器失败: " + tcpSocket->errorString());} else {logTextEdit->append("已连接到服务器!");}
}void MainWindow::onSendButtonClicked()
{// 发送消息到服务器QString message = messageLineEdit->text();if (message.isEmpty()) {return;}tcpSocket->write(message.toUtf8());if (!tcpSocket->waitForBytesWritten(3000)) {QMessageBox::critical(this, "错误", "发送失败: " + tcpSocket->errorString());} else {logTextEdit->append("发送消息: " + message);}
}void MainWindow::onReadyRead()
{// 读取服务器的响应QByteArray response = tcpSocket->readAll();logTextEdit->append("收到服务器响应: " + response);
}void MainWindow::onError(QAbstractSocket::SocketError socketError)
{// 处理连接错误Q_UNUSED(socketError);QMessageBox::critical(this, "错误", "发生错误: " + tcpSocket->errorString());
}

三、 浅谈MQTT

  老粉丝可能知道,笔者钟情于MQTT作为远距离形象传递的手段(主要是目前这种资料比较多,笔者太菜了学不会别的),本小节就简单讲一下我的一些理解。MQTT是一种基于TCP/IP协议的"轻量级"通讯协议,该协议主要是发布/订阅(publish/subscribe)模式的。在通讯过程中, MQTT协议中有三种身份: 发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。 其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。
在这里插入图片描述
  MQTT传输的消息分为由主题(Topic)和负载(payload)两部分组成,也就我们常见的“Topic+data”的结构。除此之外,消息服务质量(QoS)管理是MQTT保证可靠传输的一大依仗,它有三种消息发布服务质量:

  1. QoSO:“至多一次”,消息发布完全依赖底层TCP/IP网络,会发生消息丢失或重复。
  2. QoS1:“至少—次”,确保消息到达,但消息重复可能会发生。
  3. QoS2:“只有一次”,确保消息到达一次。

  常见的MQTT报文有以下15种,其中可以分为三大类:连接、发布和订阅,对应MQTT的实现流程。而一个MQTT数据包由固定头(Fixed header)、可变头(Variable header)、消息体(payload)三部分构成
在这里插入图片描述
  知道以上这部分其实就差不多了,毕竟我们不是专业搞信息工程或者网络专业的,剩下的很琐碎的东西学起来就很费时费力了。

免责声明:本文参考了网上公开的部分资料,仅供学习参考使用,若有侵权或勘误请联系笔者

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

uni-app发起请求以及请求封装,上传及下载功能(六)

文章目录 一、发起网络请求1.使用及封装2. https 请求配置自签名证书3.拦截器 二、上传下载1.上传 uni.uploadFile(OBJECT)2. 下载 uni.downloadFile(OBJECT) 一、发起网络请求 uni-app中内置的uni.request()已经很强大了&#xff0c;简单且好用。为了让其更好用&#xff0c;同…

快速理解软件开源协议,以及如何选择协议

一、开源协议介绍 开源协议&#xff0c;是一个用来对软件二次分发进行限制和规范的条文规定&#xff0c;用户在使用他人开源代码的时候&#xff0c;可以根据作者选取的LICENSE获知自己能够有哪些权利去处理从原作者哪里拿到的代码。开源协议是开源社区运作的基石&#xff0c;在…

【读书笔记/深入理解K8S】集群网络

前言 上一章讲了集群控制器的一个大概的原理&#xff0c;这一章讲一下集群网络。网络是集群通信的载体&#xff0c;因为该书是阿里云团队出品的&#xff0c;所以也以阿里云的集群网络方案为例&#xff0c;其他云厂商的网络集群方案一般来说也大同小异。所以通过本章的学习&…

【计算机网络】章节 知识点总结

一、计算机网络概述 1. 计算机网络向用户提供的两个最重要的功能&#xff1a;连通性、共享 2. 因特网发展的三个阶段&#xff1a; 第一阶段&#xff1a;从单个网络 ARPANET 向互联网发展的过程。1983 年 TCP/IP 协议成为 ARPANET 上的标准协议。第二阶段&#xff1a;建成三级…

一站式教育网校系统源码开发方案:知识付费小程序搭建详解

本文将从开发的技术要点、功能模块设计、性能优化等角度&#xff0c;详解一站式教育网校系统源码的开发方案&#xff0c;并着重讲解知识付费小程序的搭建方法。 一、教育网校系统源码开发的核心需求 要搭建一套稳定、高效的教育网校系统&#xff0c;首先需要明确其核心需求。一…

Java学习Day57:碧水金睛兽!(Spring Cloud微服务1.0)

1.微服务入门 (1).单体架构与分布式架构 单体架构&#xff1a; 将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署优点&#xff1a; 架构简单、部署成本低 &#xff1b; 缺点&#xff1a; 耦合度高项目打包部署到Tomcat&#xff0c;用户直接访问。用户量增加后…

AI直播带货场景切换模块的搭建!

AI直播带货&#xff0c;作为电商领域的新宠&#xff0c;正以其独特的魅力和高效的营销手段&#xff0c;引领着销售模式的新变革。 在AI直播带货中&#xff0c;场景切换模块是不可或缺的一部分&#xff0c;它不仅能够提升观众的观看体验&#xff0c;还能更好地展示商品&#xf…

华为HCIP —— QinQ技术实验配置

一、QinQ的概述 1.1QinQ的概念 QinQ&#xff08;802.1Q in 802.1Q&#xff09;技术是一项扩展VLAN空间的技术&#xff0c;通过在原有的802.1Q报文基础上再增加一层802.1Q的Tag来实现。 1.2QinQ封装结构 QinQ封装报文是在无标签的以太网数据帧的源MAC地址字段后面加上两个VL…

Linux grep命令详解(多图、多示例)

文章目录 grep基本说明grep参数简单示例列举参数-v(反选)-r -l -H -i(目录子目录、只打印匹配文件、输出文件名、忽略大小写)-c -n -o(匹配次数、输出行号、只打印匹配)-A -B -C(前后行) 正则表达式基本正则表达式与扩展正则表达式 grep示例附录:正则表达式基本字符特殊字符Per…

Hadoop---MapReduce(3)

MapTask工作机制 &#xff08;1&#xff09;Read阶段&#xff1a;MapTask通过InputFormat获得的RecordReader&#xff0c;从输入InputSplit中解析出一个个key/value。 &#xff08;2&#xff09;Map阶段&#xff1a;该节点主要是将解析出的key/value交给用户编写map()函数处理&…

UI界面设计入门:打造卓越用户体验

互联网的迅猛发展催生了众多相关职业&#xff0c;其中UI界面设计师成为互联网行业的关键角色之一。UI界面设计无处不在&#xff0c;影响着网站、应用程序以及其他数字平台上的按钮、菜单布局、色彩搭配和字体排版等。UI设计不仅仅是字体、色彩和导航栏的组合&#xff0c;它的意…

jmeter基础01-3_环境准备-Linux系统安装jdk

Step1. 查看系统类型 打开终端&#xff0c;命令行输入uname -a&#xff0c;显示所有系统信息&#xff0c;包括内核名称、主机名、内核版本等。 如果输出是x86_64&#xff0c;则系统为64位。如果输出是i686 或i386&#xff0c;则系统为32位。 Step2. 官网下载安装包 https://www…

2024年海淀区中小学生信息学竞赛校级预选赛试题与解析(第二部分程序阅读题(1-4))

第一题代码&#xff1a; #include<bits/stdc.h> using namespace std; int n, cnt;int main() {cin >> n; // 读取输入的整数 nfor (int i 1; i < n; i) // 从 1 到 n-1 的整数进行遍历if (n % i 0) // 如果 i 是 n 的约数cnt; …

ELK日志

一&#xff0c;Elastic Stack 在企业的常用架构 1&#xff0c;没有日志收集系统运维工作的日常"痛点"概述 如上图所示&#xff0c;简单画了一下互联网常用的一些技术栈相关架构图&#xff0c;请问如果让你对上图中的各组件日志进行收集&#xff0c;分析&#xff0c;存…

SAP RFC 用户安全授权

一、SAP 通讯用户 对于RFC接口的用户&#xff0c;使用五种用户类型之一的“通讯”类型&#xff0c;这种类型的用户没有登陆SAPGUI的权限。 二、对调用的RFC授权 在通讯用户内部&#xff0c;权限对象&#xff1a;S_RFC中&#xff0c;限制进一步可以调用的RFC函数授权&#xff…

文件操作:Xml转Excel

1 添加依赖 Spire.Xls.jar <dependency><groupId>e-iceblue</groupId><artifactId>spire.xls</artifactId><version>5.3.3</version></dependency>2 代码使用 package cctd.controller;import com.spire.xls.FileFormat; im…

【FL0014】基于SpringBoot和微信小程序的个人健康管理系统

&#x1f9d1;‍&#x1f4bb;博主介绍&#x1f9d1;‍&#x1f4bb; 全网粉丝10W,CSDN全栈领域优质创作者&#xff0c;博客之星、掘金/知乎/b站/华为云/阿里云等平台优质作者、专注于Java、小程序/APP、python、大数据等技术领域和毕业项目实战&#xff0c;以及程序定制化开发…

数据库_SQLite3

下载 1、更新软件源&#xff1a; sudo apt-get update 2、下载SQLite3&#xff1a; sudo apt-get install sqlite3 3、验证&#xff1a; sqlite3启动数据库&#xff0c;出现以下界面代表运行正常。输入 .exit 可以退出数据库 4、安装sqlite3的库 sudo apt-get install l…

鸿蒙进阶-List组件

hello大家好&#xff0c;这里是鸿蒙开天组&#xff0c;今天我们来讲讲常用的List组件&#xff0c;也就是列表组件。 List组件 List 组件的基本用法&#xff0c;可以用它来展示列表&#xff0c;并且实现列表滚动&#xff0c;日常开发的时候还可以用它来实现更为复杂的效果。 …

EDA技术简介

目录 可编程逻辑器件 CPLD/FPGA 基于查找表结构的FPGA 硬件描述语言 EDA软件 EDA技术的 应用领域 电子系统的设计方法 EDA (Electronic Design Automation,电子设计自动化) 以可编程逻辑器件 (Programmable Logic Device,简称PLD)为实现载体、以硬件描述语言 (Hardwar…