基于TCP的Qt网络通信

news2025/1/5 16:03:46

基于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.coloradmin.cn/o/2270310.html

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

相关文章

java vscode springboot 问题汇总

问题1 VSCODE配置SpringBoot,创建新项目运行时报错程序包不存在 找不到符号解决方法 选择Run Java即可 , 不是Run Code DemoApplication.java:3: 错误: 程序包org.springframework.boot不存在 import org.springframework.boot.SpringApplication; …

BLIP论文笔记

论文地址 BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation 论文思想 其实Clip就相当于只用了ITC

linux上使用cmake编译的方法

一、hello 例程仅基于一个cpp文件 C文件或工程进行编译时可以使用g指令(需要对每一个程序和源文件分别使用g指令编译),当程序变大时,一个工程文件往往会包含很文件夹和源文件,这时我们需要的编译指令将越来越长&#…

Speech Recognition vs. Voice Recognition | 语音识别工作原理 | 模型训练 | 应用

注:Speech Recognition 与 Voice Recognition 机翻混淆,未校。 Speech Recognition vs. Voice Recognition: In Depth Comparison 语音识别与语音识别:深度比较 Calendar12 July 2023 Have you ever stopped to think about how your voice…

Tushare提示本接口即将停止更新,请尽快使用Pro版接口:https://tushare.pro/document/2

1、解决办法 tushare pro版本需要注册登录后获取tocken然后在代码中配置接口即可。 2、如何获取tushare? tushare是免费、开源的python财经数据接口,现在使用需要先注册tushare账号 1、跳转到tushare注册页面 Tusharez注册 Tushare数据 2、注册成功…

高频 SQL 50 题(基础版)_1068. 产品销售分析 I

销售表 Sales: (sale_id, year) 是销售表 Sales 的主键(具有唯一值的列的组合)。 product_id 是关联到产品表 Product 的外键(reference 列)。 该表的每一行显示 product_id 在某一年的销售情况。 注意: price 表示每…

【Ubuntu】Ubuntu server 18.04 搭建Slurm并行计算环境(包含NFS)

Ubuntu server 18.04 搭建Slurm并行计算环境(包含NFS) 一、Munge 认证模块 1.1、安装 munge 主节点和子节点都安装munge #安装 sudo apt update && sudo apt install munge libmunge-dev#设置开机启动 sudo systemctl enable munge sudo syste…

电脑主机后置音频插孔无声?还得Realtek高清晰音频管理器调教

0 缘起 一台联想电脑,使用Windows 10 专业版32位,电脑主机后置音频插孔一直没有声音,所以音箱是接在机箱前面版的前置音频插孔上的。 一天不小心捱到了音箱的音频线,音频线头断在音频插孔里面了,前置音频插孔因此用不…

Flink源码解析之:如何根据算法生成StreamGraph过程

Flink源码解析之:如何根据算法生成StreamGraph过程 在我们日常编写Flink应用的时候,会首先创建一个StreamExecutionEnvironment.getExecutionEnvironment()对象,在添加一些自定义处理算子后,会调用env.execute来执行定义好的Flin…

矩阵运算提速——玩转opencv::Mat

介绍:用Eigen或opencv::Mat进行矩阵的运算&#xff0c;比用cpp的vector或vector进行矩阵运算要快吗? 使用 Eigen 或 OpenCV 的 cv::Mat 进行矩阵运算通常比使用 std::vector<int> 或 std::vector<double> 更快。这主要有以下几个原因&#xff1a; 优化的底层实现…

Spire.PDF for .NET【页面设置】演示:向 PDF 添加平铺背景图像

平铺背景通常是指用一个或多个小图像重复填充的背景。在本文中&#xff0c;您将学习如何在 PDF 中平铺图像&#xff0c;并使用 C# 和 VB.NET 为您的 PDF 创建平铺背景。 Spire.PDF for .NET 是一款独立 PDF 控件&#xff0c;用于 .NET 程序中创建、编辑和操作 PDF 文档。使用 …

文件本地和OSS上传

这里写目录标题 前端传出文件后端本地存储阿里云OSS存储上传Demo实现上传ConfigurationProperties 前端传出文件 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>上传文件</title> </head&g…

SpringCloud源码分析-Gateway

Gateway核心原理&#xff0c;请求经过一系列的责任链最后到达服务端。

两个等号和三个等号(待查资料)

1太癫了&#xff0c;居然时要才行&#xff0c;都不行 2. 三等号的结果 .。。。。毁灭吧

什么是神经网络?神经网络的基本组成部分训练神经网络激活函数有哪些局限性和挑战

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c; 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把…

《Java核心技术II》流中的filter、map和flatMap方法

filter、map和flatMap方法 filter filter通过转换产生过滤后的新流,将字符串流转化为只包含长单词的另一个流。 List words ...; Stream longWords words.stream().filter(w->w.length()>12) filter类型是Predicate(谓词&#xff0c;表示动作)类型对象&#xff0c…

linux进阶

目录 变量 shell变量 环境变量 预定义变量 位置变量 其他 管道与重定向 管道 重定向 shell脚本 分支结构 循环结构 数组 脚本实例 变量 shell变量 shell变量&#xff1a;shell程序在内存中存储数据的容器 shell变量的设置&#xff1a;colorred 将命令的结果赋值…

阿赵的MaxScript学习笔记分享十六《MaxScript和WinForm交互》

MaxScript学习笔记目录 大家好&#xff0c;我是阿赵。   之前有网友给我留言说MaxScript和DotNet的WinForm界面交互有问题。我回头看了一下&#xff0c;发现之前的MaxScript文章是漏了这部分没有说明&#xff0c;这里补充一下。这里的内容主要是用C#写一个WinForm界面&#x…

出海新势力:巴西短剧的崛起与出海系统开发平台的赋能

在全球短剧蓬勃发展的浪潮中&#xff0c;巴西短剧宛如一颗耀眼的新星&#xff0c;迅速在拉美文娱的天空中崭露头角&#xff0c;成为备受瞩目的潜力股&#xff0c;正以独特的魅力吸引着越来越多观众的目光&#xff0c;在国际舞台上绽放出属于自己的光彩。 巴西短剧缘何火爆&…

HTML5新特性|01 音频视频

音频 1、Audio (音频) HTML5提供了播放音频文件的标准 2、control(控制器) control 属性供添加播放、暂停和音量控件 3、标签: <audio> 定义声音 <source> 规定多媒体资源,可以是多个<!DOCTYPE html> <html lang"en"> <head><…