如何正确使用QTcpSocket的readyRead信号?

2023-10-27

一、问题描述:

你之所以会来看我这篇文章,大概是遇到了一下几个问题:

1、使用QTcpSocket时,readyread函数没有触发,或者触发了,但是触发次数不是自己想象的那样。

2、readyread槽函数中,接收到的数据不对。

我们先看一下Qt官方文档的说法:

官方文档中对readyread函数解释很简短:

    This signal is emitted once every time new data is available for reading from the device's current read channel. It will only be emitted again once new data is available, such as when a new payload of network data has arrived on your network socket, or when a new block of data has been appended to your device.

//让我来解释给你这句话的意思,解释完你就会有新的认识。//

       每一次,在当前用来存放读数据的位置中(也就是可读缓冲区),有可读数据可用,都会发送这个信号。当新的数据到来的时候,这个信号还会再发送且仅发送一次。比如:新的网络数据到达你的网络socket,或者新的数据块添加到你的设备。

       我们一句一句话来理解,首先是:“每一次,在当前用来存放读数据的位置中(也就是可读缓冲区),有可读数据可用,都会发送这个信号”。这句话的意思是,当你的QTcpSokcet第一次接收到数据,也就是socket的缓冲区从没有数据变为有数据时,触发一次。

       接下来非常关键的一句话是:“当新的数据到来的时候,这个信号还会再发送且仅发送一次。”很多朋友对新的数据到来的错误理解是,发送端对应的QTcpSokcet写一次,也就是write函数调用一次,那么接收方就会有新的数据到达,于是readyread信号被触发一次。这个理解是错误的。经过测试,我们发现事实是这样的:发送和接收的次数是没有一一对应关系的。发送端write函数调用一次,假如这一次write了2M的数据,那么接收方的readyread信号就往往会触发两次以上。反过来,如过发送端write函数被调用两次或两次以上,每次发送的数据量很小,比如两三个字节,那么接收方的readyread信号也有可能只触发一次。

        这是什么回事呢?文档明明说有新的数据来,就会帮我触发一次。其实啊,这里说新的数据来,不是说从发送端有新的数据来到你的主机,而是数据从Tcp/ip协议栈到达接收端的Qt应用程序,也就是系统io缓冲区到达Qt应用程序,数据从系统到达Qt应用程序一次,readyread信号就会触发一次。

        还有一个非常要注意的词就是“only once”,仅仅一次。什么意思呢?其实是这样的,第一次数据来的时候,触发一次readyread信号,但如果此时你的readyread槽函数还没有及时执行,或者从根本上说QTcpsocket对象的byteAvailable函数返回值还不为0,而新的数据又来了而且来了很多次,那么,这些所有的都将会只再触发一次readyread信号。如果此时你的readyread槽函数执行了,那么这时候来的新的数据就会触发第三个readyread信号。也就是说,还没有响应的readyread信号最多只有两个。想想也是啊,如果我发送端一直发送数据,你的系统就一直接收并将数据发送给你的应用,然后每得到一个字节都触发一次readyRead信号,触发到成千上万个,那击崩一个服务器不就很简单了?

       最后一个关键词,那就是“数据”。通过上面的介绍,你可能也意识到了,既然发送和接收没有一一对应关系,那么我接收到的东西到底是什么样子的?这时候你就需要对数据流有一定的认识。数据从另一端以流的方式流进了你的机子。数据到了的时候,系统就会通过数据报的端口来识别这个数据是要发送给这台机子的哪个应用程序。注意TCP和udp的数据是有区别的,tcp数据包没有边界,udp有。也就是说对于tcp,数据是连在一起的分不开的,最小粒度是1字节。发送端的应用程序write函数一次写了多少数据,接收方的系统是不知道的。那么接收方系统到底接收到多少数据才发送给qt应用程序呢?这个算法是这样的:超时和超过缓冲。超时:无论来了多少数据,超过这个时间,系统就会发送当前接收到的数据给qt应用程序。超过缓冲,在未超时的情况下,系统缓冲区满了,系统就会将数据发送给qt应用程序。系统TCP/IP缓冲最大是65536个字节。

        根据以上机制,在readyread槽函数中,调用QTcpSocket的byteAvailable函数返回的值,是不可预知的,取决于系统发给应用时,发送的数量,这个数量的最大值就是65536字节。这个byteAvailable函数返回的值,就是本次readyread槽函数中所能读到的网络数据量。如果在你正在读取数据时,又有新的数据到来,byteAvailable返回的值是不会被影响的。你读了多少数据,byteAvailable就会减去多少数据。如果用的是readAll函数就是读完,byteAvailable就会返回0。注意:网上流传这很多用流的方式接收数据,在readyread槽函数还没有结束之前,QTcpSocket缓存数据是不会清除掉的,所以byteAvailable返回值从槽函数开始到结束都不会变。(流其实就是序列化,流进和流出数据类型要保持一致,谨慎使用。)readyRead信号这样的触发机制,就可能会存在黏包问题,关于黏包问题的解释和解决方案网上已经有很多很优秀的文章了,我就不赘述了。

       最后,要是还没有解决你的readyread函数还是没有触发,看看是不是防火墙有没有禁掉你的qt应用,有没有关掉VPN。
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何正确使用QTcpSocket的readyRead信号? 的相关文章

  • 如何在 QT 安装程序框架中区分每用户安装与系统范围安装?

    我正在使用一些名为 pgModeler 的应用程序 它的当前版本提供了一个基于 QT 安装程序框架的安装程序 Windows 上该安装程序的问题是它安装每个用户的开始菜单条目 https github com pgmodeler pgmod
  • 如何在Qt无框窗口中实现QSizeGrip?

    如何使用 Qt 无框窗口实现 QSizeGrip 代码会是什么样的 您只需在布局内窗口的一角添加 QSizeGrip 即可使其保持在该角落 QDialog dialog new QDialog 0 Qt FramelessWindowHin
  • 具有多个父项的 Qt 树模型

    我想构建一棵树 其中一个元素可以引用另一个元素 我想要构建的树是 像这样的东西 A B C D E F P this is a pointer to C D first child of C E second child of C I fo
  • 如何为 qmlRegisterSingletonType 实现单例提供程序?

    我想在 QML 中使用 C 类作为 Singleton 实例 并认为我必须使用 qmlRegisterSingletonType 注册它们 此函数需要一个提供已注册 C 类的实例的函数 我在 Windows 上使用最新的 Qt 5 3 1
  • 使用 QTextCursor 选择一段文本

    使用 Qt 框架选择文本片段时遇到问题 例如 如果我有这个文件 没有时间休息 我想选择 ime for r 并从文档中删除这段文本 我应该如何使用 QTextCursor 来做到这一点 这是我的代码 QTextCursor cursor n
  • 用 C++/Qt 编写的程序中的 RTF / doc / docx 文本提取

    我正在写一些程序Qt https en wikipedia org wiki Qt 28software 29 C 我需要从中读取文本微软Word https en wikipedia org wiki Microsoft Word RTF
  • new 运算符(以及 malloc)无法分配约 450 MB 的内存 [重复]

    这个问题在这里已经有答案了 我正在开发一个程序 该程序在内存中存储大约 2 2 亿个短值的数组 该数据块的分配方式如下 short arrayName new short SIZE OF ARRAY 然后将文件的内容读入内存 在团队中的另一
  • QT:删除QGridLayout中QLabel之间的空格

    我将一些具有不同颜色的 QLabels 添加到 QGridLayout 作为 QWidget 的布局 现在我在每个 Qlabel 与下一个 Qlabel 之间有一个间距 我想将其删除 我尝试将标签的边距设置为 0 将 GridLayout
  • 清除pyqt中布局中的所有小部件

    有没有办法清除 删除 布局中的所有小部件 self plot layout QtGui QGridLayout self plot layout setGeometry QtCore QRect 200 200 200 200 self r
  • C++ SQL 查询构建库

    我正在寻找一个提供与 c SelectQueryBuilder 库类似功能的 c 库 http www codeproject com Articles 13419 SelectQueryBuilder Building complex a
  • 使用 OpenGL 渲染 QImage

    与我相关的其他问题 https stackoverflow com questions 20126354 render qimage from sooffscreenrenderer in qglwidget 我认为更核心的问题是 如何渲染
  • Qt:不完整类型和前向声明的使用无效

    我有一些误解 A h ifndef A H define A H include B h class A public B Q OBJECT public A endif A cpp include A h A A B ui gt blan
  • 如何在 Qt 应用程序中嵌入 Python 解释器?

    有没有一种简单的方法可以将 Python 解释器嵌入到 Qt 应用程序中 如果可能的话 我希望有一个跨平台的解决方案 这就是目的PythonQt http pythonqt sourceforge net 它支持 Windows Linux
  • 了解 Qt3D 创建的网格

    我创建了一个 Qt3D 网格 如下所示 Qt3DCore QEntity newEntity new Qt3DCore QEntity Qt3DExtras QConeMesh mesh new Qt3DExtras QConeMesh m
  • 无法运行 Qt 应用程序:找不到版本“Qt_5”

    我运行 Ubuntu 16 04 LTS 我的问题是我无法运行可以编译的 Qt5 应用程序 这是我尝试运行它时得到的结果 home user Desktop sconfig dist Release GNU Linux SCongif us
  • Qt QML 数据模型似乎不适用于 C++

    我一直在使用中的示例http doc qt digia com 4 7 qdeclarativemodels html http doc qt digia com 4 7 qdeclarativemodels html这是 QML 声明性数
  • 使用 QGraphicsScene 实现流畅的动画

    我希望我的问题并不总是同样的问题 我有一个 QGraphicsScene 它的项目是一些 QGraphicsPixmap 我用一个计时器来移动它们 每秒 SetX 10 我设置 10是因为窗口大100 使用这个解决方案我的动画不流畅 我想我
  • QTabWidget 选项卡在垂直方向,但文本在水平方向

    我正在尝试用 C Qt 制作一个带有这样的侧边栏的应用程序 但是当将 QTabWidget 方向设置为西时 它会使文本垂直 如何让文本位于左侧 但水平对齐 PS 我不需要图标 提前致谢 您可以使用QListWidget http doc q
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 在 Qt 中自动调整标签文本大小 - 奇怪的行为

    在 Qt 中 我有一个复合小部件 它由排列在 QBoxLayouts 内的多个 QLabels 组成 当小部件调整大小时 我希望标签文本缩放以填充标签区域 并且我已经在 resizeEvent 中实现了文本大小的调整 这可行 但似乎发生了某

随机推荐

  • vue中使用百度地图 添加标记物,点击标记物弹窗,画运动轨迹,位置纠偏,逆地址解析

    在vue项目中使用百度地图 添加标记物 位置纠偏 信息弹窗 画轨迹 坐标转换 逆地址解析 参考vue baidu map开发文档 安装 npm install vue baidu map save 全局注册 在main js中引入以下代码
  • 【Vue】关于开发中本地图片加载失败的经验总结

    文章目录 1 图片存放在assets 2 图片存放在static中 3 其他需要注意的点 我的源码 img或者el avatar中的src没有提供静态值 而是绑定一个动态变量 如果这个变量的路径是存放在assets里 则图片会加载失败 1
  • nginx代理路径配置总结

    一 发现问题 配置nginx代理的时候 发现location配置的路径和代理的上下文路径的组合不同 服务端接收到的uri的路径不同 导致了controller的RequestMapping匹配出现问题 所以就仔细研究了一下nginx路径配置
  • 对象属性拷贝(BeanUtils.copyProperties)用法

    系列文章目 对象属性拷贝 BeanUtils copyProperties 用法 一 BeanUtils copyProperties参数赋值顺序 根据导包不同 方式不同 一个为org springframework beans BeanU
  • MySQL数据库渗透及漏洞利用总结

    Mysql数据库是目前世界上使用最为广泛的数据库之一 很多著名公司和站点都使用Mysql作为其数据库支撑 目前很多架构都以Mysql作为数据库管理系统 例如LAMP 和WAMP等 在针对网站渗透中 很多都是跟Mysql数据库有关 各种Mys
  • FCKEditor 2.3.2 的type漏洞修复

    从网上下了最新的FCKeditor 2 3 2和对应的JSP整合文件FCKeditor 2 3 安装后进行测试 发现type漏洞仍然存在 汗 漏洞情况是 或在type后面跟上一个非file image flash media参数 就可以上传
  • 探索数据分析与可视化:使用R语言实现

    探索数据分析与可视化 使用R语言实现 概述 数据分析与可视化是现代数据科学中至关重要的环节 R语言作为一种强大的统计分析工具和编程语言 提供了丰富的功能和库来处理数据 进行统计分析和生成可视化图表 本文将介绍如何使用R语言进行数据分析与可视
  • 关于 cocos2d-x win32 版本的 cpu 占用改良

    初学 c2dx 下载的 2 02 版本 发现其 HelloWorld 演示项目 居然一直占据了 100 的 CPU 猜测它有可能是在主循环里使用了 Sleep 0 一搜 果然定位到具体代码 它位于 cocos2dx platform win
  • Flutter常用布局方式

    文章目录 flutter 布局介绍 一 Container 布局 1 属性 2 示例 二 线性布局 1 说明 2 属性 3 示例 三 弹性布局 Flex 1 属性 2 Expanded 的使用 3 示例 四 流式布局 1 说明 2 属性 3
  • 方差、标准差、平方差、残差

    2018 06 21 创建人 Ruo Xiao 邮箱 xclsoftware 163 com 2018 06 29 修改人 Ruo Xiao 增加对残差的说明 一 方差 1 定义 数据分别与其平均数的差的平方和的平均数 由 D 表示 2 意
  • Nssm 安装Window服务

    环境 Wind10 1 下载nssm exe 官网 http nssm cc download 2 解压 根据操作系统选择32位或64位nssm 在该目录启动命令行窗口 3 服务注册 命令行输入 nssm exe install XX或者n
  • 在CentOS7上安装RabbitMQ(RPM安装方式)

    首先需要安装erlang 参考 http fedoraproject org wiki EPEL FAQ howtouse rpm Uvh https download fedoraproject org pub epel epel rel
  • SQL命令笔记

    sql中的排序倒序 排序采用 order by 子句 order by 后面跟上排序字段 排序字段可以放多个 多个采用逗号间隔 order by默认采用升序 asc 如果存在 where 子句 那么 order by 必须放到where 语
  • 使用VS配置OCCI环境

    一 配置方法 1 准备好occi的两个配置文件sdk与basic 之后将VS内的设置环境为release x64 2 c c 常规 附加库包含目录 F programmsoftware occi instantclient sdk wind
  • IDEA插件之 时序图 -- Sequence Diagram

    安装插件 使用 在方法上右击选择 Sequence Diagram 设置参数 可在控制台内查看时序图结果
  • 【数据结构与算法】树状数组

    Fenwick Tree 树状数组 Binary Indexed Tree 又称 Fenwick Tree 是一种基于数组实现的数据结构 用于高效地动态维护前缀和 树状数组可以在 O log n
  • uni-app 高度自适应

    方法一已知固定高度 注意 scrollH 初始值不等大于最终显示的高度 如果封装组件 onReady onLoad 获取可视区域高度 减去固定高度 uni getSystemInfo success res gt this scrollH
  • nacos--基础--1.2--理论--概念

    nacos 基础 1 2 理论 概念 1 地域 物理的数据中心 资源创建成功后不能更换 2 可用区 同一地域内 电力和网络互相独立的物理区域 同一可用区内 实例的网络延迟较低 3 接入点 地域的某个服务的入口域名 4 命名空间 用于进行租户
  • 国外程序员的BASIC情结——我的编程生涯始于BASIC

    关于BASIC Edsger Dijkstra曾经说过这么一段话 那些已经学过BASIC的学生是不可教化的 再去教他们优秀的编程风格注定徒劳无功 他们已经脑残 再生无望 成不了优秀的程序员 BASIC是Beginner sAll purpo
  • 如何正确使用QTcpSocket的readyRead信号?

    一 问题描述 你之所以会来看我这篇文章 大概是遇到了一下几个问题 1 使用QTcpSocket时 readyread函数没有触发 或者触发了 但是触发次数不是自己想象的那样 2 readyread槽函数中 接收到的数据不对 我们先看一下Qt