基于TCP的Qt网络通信

基于TCP的Qt网络通信

项目源码:https://github.com/say-Hai/TcpSocketLearn/tree/QTcpSocket

在标准C++没有提供专门用于套接字通信的类,所以只能使用操作系统提供的基于C的API函数,但是Qt就不一样了,它是C++的一个框架并且里边提供了用于套接字通信的类(TCP、UDP)这样就使得我们的操作变得更加简单。

使用Qt提供的类进行基于TCP的套接字通信需要用到两个类:(都属于网络模块network)

  • QTcpServer服务器类,用于监听客户端连接以及和客户端建立连接
  • QTcpSocket通信的套接字类(IO操作),客户端、服务器端都需要使用。(与文件操作类QFile同属于同一个祖先QIODevice

一、QTcpServer类

QTcpServer类用于监听客户端连接以及和客户端建立连接

1.1 公共成员函数

  • 1⭐构造函数

    • QTcpServer::QTcpServer(QObject *parent = Q_NULLPTR);
      
  • 2⭐给监听的套接字设置监听

    • //★类似于Socket中的 bind + listen
      bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
      //使用QHostAddress类对IPv4/6进行了封装,可以直接通过点分十进制赋值// 判断当前对象是否在监听, 是返回true,没有监听返回false
      bool QTcpServer::isListening() const;//返回监听的服务器地址
      QHostAddress QTcpServer::serverAddress() const;
      // 返回服务器的端口
      quint16 QTcpServer::serverPort() const
      
  • 4⭐得到和客户端建立连接之后用于通信的QTcpSocket套接字对象

    • QTcpSocket套接字对象QTcpServer的一个子对象,当QTcpServer对象析构的时候会自动析构这个子对象,建议用完之后自己手动析构这个通信的QTcpSocket对象。

    • QTcpSocket *QTcpServer::nextPendingConnection();
      //返回值:返回用于通信的套接字对象,建议自己手动释放内存
      
  • 阻塞等待客户端发起的连接请求

    • 不推荐在单线程程序中使用,建议使用非阻塞方式处理新连接,即使用信号 newConnection()

    • bool QTcpServer::waitForNewConnection(int msec = 0, bool *timedOut = Q_NULLPTR);
      

1.2 信号

  • 当接受新连接导致错误时,将发射如下信号

    • void QTcpServer::acceptError(QAbstractSocket::SocketError socketError);
      //socketError:描述发生错误的相关信息
      
  • 3⭐每次有新连接可用时都会发出 newConnection() 信号。

    • void QTcpServer::newConnection();
      
  • 有数据可读取时,发送readyRead

1.3 服务器连接的API调用顺序

  • 创建 QTcpServer 实例

    • QTcpServer *server = new QTcpServer(this);
      
  • 监听端口 QTcpServer::listen()

    • server->listen(QHostAddress::Any, 12345)
      
  • 连接 newConnection() 信号

    • connect(server, &QTcpServer::newConnection, this, &MyServer::onNewConnection);
      
  • 处理新连接

    • 在槽函数 onNewConnection() 中获取新的 QTcpSocket,它代表与客户端的连接。

    • void MyServer::onNewConnection() {QTcpSocket *clientSocket = server->nextPendingConnection();// 连接信号与槽connect(clientSocket, &QTcpSocket::readyRead, this, &MyServer::onReadyRead);connect(clientSocket, &QTcpSocket::disconnected, this, &MyServer::onDisconnected);
      }
      

二、QTcpSocket

QTcpSocket是一个套接字通信类,不管是客户端还是服务器端都需要使用。在Qt中发送和接收数据也属于IO操作(网络IO)

继承关系:

image-20210512174459252

2.1 公共成员函数

  • 构造函数

    • QTcpSocket::QTcpSocket(QObject *parent = Q_NULLPTR);
      
  • 连接服务器需要指定服务器端绑定的IP和端口信息

    • [virtual] void QAbstractSocket::connectToHost(const QString &hostName, quint16 port, OpenMode openMode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol);void QAbstractSocket::connectToHost(const QHostAddress &address, quint16 port,OpenMode openMode = ReadWrite);
      
  • 读写数据

    • 在Qt中不管调用读函数,还是调用写函数,操作的对象都是由Qt框架维护的一块内存。因此,调用了发送函数数据不一定会马上被发送到网络中,调用了接收函数也不是直接从网络中接收数据,关于底层的相关操作是不需要使用者来维护的。

    • // 指定可接收的最大字节数 maxSize 的数据到指针 data 指向的内存中
      qint64 QIODevice::read(char *data, qint64 maxSize);
      // 指定可接收的最大字节数 maxSize,返回接收的字符串
      QByteArray QIODevice::read(qint64 maxSize);
      // 将当前可用操作数据全部读出,通过返回值返回读出的字符串
      QByteArray QIODevice::readAll();// 发送指针 data 指向的内存中的 maxSize 个字节的数据
      qint64 QIODevice::write(const char *data, qint64 maxSize);
      // 发送指针 data 指向的内存中的数据,字符串以 \0 作为结束标记
      qint64 QIODevice::write(const char *data);
      // 发送参数指定的字符串
      qint64 QIODevice::write(const QByteArray &byteArray);
      

2.2 信号

  • QTcpSocket进行套接字通信的过程中,如果该类对象发射出readyRead()信号,说明对端发送的数据已到达,之后可以调用 read 函数接收数据。
 void QIODevice::readyRead();
  • 调用connectToHost()函数并成功建立连接之后发出connected()信号。
 void QAbstractSocket::connected();
  • 套接字断开连接时发出disconnected()信号。
void QAbstractSocket::disconnected();

2.3 客户端连接的API调用顺序

  • 创建客户端套接字用于与服务器通信

    • QTcpSocket *socket = new QTcpSocket(this);
      
  • 客户端的信号与槽函数绑定,以便监听事件,例如连接成功、数据接收等。

    • connect(socket, &QTcpSocket::connected, this, &YourClass::onConnected);
      connect(socket, &QTcpSocket::readyRead, this, &YourClass::onReadyRead);
      connect(socket, &QTcpSocket::errorOccurred, this, &YourClass::onError);
      
  • 使用 connectToHost 函数连接到目标服务器。

    • socket->connectToHost("127.0.0.1", 12345);
      

三、通信流程

3.1 服务器端

通信流程:

  • 创建套接字服务器QTcpServer对象
  • 通过QTcpServer对象设置监听,即:QTcpServer::listen()
  • 基于QTcpServer::newConnection()信号检测是否有新的客户端连接
  • 如果有新的客户端连接调用QTcpSocket *QTcpServer::nextPendingConnection()得到通信的套接字对象
  • 使用通信的套接字对象QTcpSocket和客户端进行通信

3.2 客户端

通信流程:

  • 创建通信的套接字类QTcpSocket对象
  • 使用服务器端绑定的IP和端口连接服务器QAbstractSocket::connectToHost()
  • 使用QTcpSocket对象和服务器进行通信

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

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

相关文章

[CCGridW 2023]Performance Modelling of Graph Neural Networks

论文网址:Performance Modelling of Graph Neural Networks | IEEE Conference Publication | IEEE Xplore 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正&#xf…

git reset --hard(重置到当前提交,所有未提交的更改都会被永久丢弃)

git reset --hard 是一个强大的命令,它会将你的工作目录、暂存区和当前分支的 HEAD 指针重置到指定的提交状态,所有未提交的更改都会被永久丢弃。因此,使用这个命令时需要非常小心。 基本用法 重置到当前提交(丢弃所有未提交的更…

springboot 整合 rabbitMQ (延迟队列)

前言: 延迟队列是一个内部有序的数据结构,其主要功能体现在其延时特性上。这种队列存储的元素都设定了特定的处理时间,意味着它们需要在规定的时间点或者延迟之后才能被取出并进行相应的处理。简而言之,延时队列被设计用于存放那…

PLC(01)

一.职业规划 电路----------------->电工------------------>电气-------------------plc---------------------DCS--------------------> 机器人 二.交流电直流电的概念 1.交流电AC alternating current 大小方向随时间发生周期性变化 2.直流电 Direct current…

基本算法——分类

目录 创建项目 导入依赖 加载数据 特征选择 学习算法 对新数据分类 评估与预测误差度量 混淆矩阵 通过模型的预测结果生成 ROC 曲线数据 选择分类算法 完整代码 结论 创建项目 首先创建spring boot项目,我这里用的JDK8,springboot2.7.6&…

2024年中国新能源汽车用车发展怎么样 PaperGPT(二)

用车趋势深入分析 接上文,2024年中国新能源汽车用车发展怎么样 PaperGPT(一)-CSDN博客本文将继续深入探讨新能源汽车的用车强度、充电行为以及充电设施的现状。 用车强度 月均行驶里程:2024年纯电车辆月均行驶超过1500公里&…

典型常见的基于知识蒸馏的目标检测方法总结三

来源:Google学术2023-2024的顶会顶刊论文 NeurIPS 2022:Towards Efficient 3D Object Detection with Knowledge Distillation 为3D目标检测提出了一种知识蒸馏的Benchmark范式,包含feature的KD,Logit的cls和reg的KD&#xff0c…

2024年中国新能源汽车用车发展怎么样 PaperGPT(一)

概述 在国家政策的强力扶持下,2024年中国新能源汽车市场迎来了新的发展机遇。本文将基于《中国新能源汽车用车报告(2024年)》的数据,对新能源汽车的市场发展和用车趋势概述。 新能源汽车市场发展 政策推动:国家和地…

Ceph 手动部署(CentOS9)

#Ceph手动部署、CentOS9、squid版本、数字版本19.2.0 #部署服务:块、对象、文件 一、部署前规划 1、兼容性确认 2、资源规划 节点类型节点名称操作系统CPU/内存硬盘网络组件安装集群节点CephAdm01CentOS94U/8GOS:40G,OSD:2*100GIP1:192.169.0.9(管理&集群),IP2:…

CUDA与Microsoft Visual Studio不兼容问题

简介:在安装一些 python库时,涉及到第三方库(特别是需要引用 C 代码)时,通常的安装方式会涉及到编译过程,通常称为"源代码安装"(source installation),或是 “…

网络安全 | 企业网络安全管理

网络安全 | 企业网络安全管理 一、前言二、企业网络安全面临的威胁2.1 网络攻击类型2.2 数据泄露风险2.3 恶意软件感染 三、企业网络安全管理的策略与措施3.1 网络架构安全设计3.2 访问控制机制3.3 数据加密技术3.4 员工安全培训 四、企业网络安全监测与应急响应体系4.1 安全监…

算命占卜网php源码/设计书/2025八字运势怎么通过php测算

引言 随着人们对传统文化的重视,八字算命逐渐成为很多人了解命运的方式。为了满足这一需求,设计一个功能丰富且用户友好的八字算命网站显得尤为重要。本文将详细阐述从构思到实施的设计过程,旨在创建一个既具吸引力又富有实用价值的八字算命…

【高项】信息系统项目管理师(二)项目管理概论

一、PMBOK的发展 项目管理知识体系(PMBOK)是由美国项目管理协会(PMI)开发的一套描述项目管理专业范围的知识体系,包含了对项目管理所需的知识、技能和工具的描述。 二、项目基本要素 2.1 项目基础 项目是为提供一项…

【无线传感网】物理层及MAC层

物理层相关概念及技术 在无线传感器网络中,物理层是数据传输的最底层,向下直接与传输介质相连,物理层协议是各种网络设备进行互联时必须遵循的底层协议 物理层的设计是无线传感器网络协议性能的决定因素 物理层的主要功能 为数据终端设备…

【SpringBoot教程】搭建SpringBoot项目之编写pom.xml

🙋大家好!我是毛毛张! 🌈个人首页: 神马都会亿点点的毛毛张 👏今天毛毛张分享的内容主要是Maven 中 pom 文件🆕,涵盖基本概念、标签属性、配置等内容 文章目录 1.前言🥭2.项目基本…

Gemma2 2B 模型的model.safetensors.index.json文件解析

Gemma2 2B 模型的 model.safetensors.index.json 文件解析 在使用 Gemma2 2B 模型或其他大型预训练模型时,model.safetensors.index.json 文件起到了索引的作用,它帮助我们了解模型的结构、参数存储方式以及如何加载模型的具体权重。本博客将深入解析该…

【游戏设计原理】41 - 游戏的核心

1. 如何理解? 这条原理主要在讲述“游戏核心”这一概念的重要性及其在游戏开发中的作用。游戏的核心是指决定游戏整体玩法和体验的核心元素,它通常是游戏的主要机制、目标或动作方式。理解这一原理时,我们可以从以下几个层面来考虑&#xff…

vue下载和上传的地址动态ip地址配置方法

vue3结合element-plus实现【下载文件】和【上传文件】的动态ip地址配置 效果图 一、修改【文件上传】静态地址 1、首先引入axios import axios from "/utils/request"; import { getToken } from "/utils/auth"; 定义 const importDialogVisible ref(…

基于 Python Django 的花卉商城系统的研究与实现

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

[Qt] 信号和槽(1) | 本质 | 使用 | 自定义

目录 一、信号和槽概述 二、本质 底层实现 1. 函数间的相互调用 2. 类成员中的特殊角色 三、使用 四. 自定义信号和槽 1. 基本语法 (1) 自定义信号函数书写规范 (2) 自定义槽函数书写规范 (3) 发送信号 (4) 示例 A. 示例一 B. 示例二 —— 老师说“上课了”&…