qt中readyread信号的使用_心动的信号cp组合有哪些

qt中readyread信号的使用_心动的信号cp组合有哪些本文主要介绍readyread函数的触发机制,会涉及到一点tcp/ip和流的知识。tcp/ip和流这方面其他朋友介绍很多了,这里我就不再赘述。本文不打算使用太过专业的词汇,一方面主要目的是让大家明白,另一方面是我也不太专业。一、问题描述:你之所以会来看我这篇文章,大概是遇到了一下几个问题:1、使用QTcpSocket时,readyread函数没有触发,或者触发了,但是触发次数不是自己想…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

本文主要介绍readyread函数的触发机制,会涉及到一点tcp/ip和流的知识。tcp/ip和流这方面其他朋友介绍很多了,这里我就不再赘述。本文不打算使用太过专业的词汇,一方面主要目的是让大家明白,另一方面是我也不太专业。

一、问题描述:

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

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。

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/195561.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 详解自动化运维平台的构建过程[通俗易懂]

    详解自动化运维平台的构建过程[通俗易懂]2013年,我加入了聚美优品,当时成都团队仅有四五个人,负责一些辅助系统的日常运维,比如查查日志等。随着公司规模逐渐的扩大,一些重要的业务往成都迁移,这对成都团队是一个非常大的挑战。业务部署最开始是手工的,我们逐渐觉得应该有一个平台来满足我们的工作,所以我们打造了一个运维平台。本文将围绕平台里有关自动化的东西做一个介绍,当然我们是一个小团队,不足的地方请大家指正。传统运维带来的坑说到运维自动化,前…

    2022年5月17日
    64
  • vs2010 序列号「建议收藏」

    vs2010 序列号「建议收藏」序列号:YCFHQ-9DWCY-DKV88-T2TMH-G7BHP从网上搜的,经测试,可用信息来源:http://blog.163.com/ldy_3881685/blog/static/32380136201031333921823/示意图环境windows7旗舰中文+vs2010旗舰英文,vs2010自己从官网下载试用版本,然后输入序列号的步骤同vs200…

    2022年7月20日
    14
  • SSDP协议_mpp协议

    SSDP协议_mpp协议privatevoidsendDatagramPacket(finalStringip){newThread(newRunnable(){@Overridepublicvoidrun(){try{MulticastSocketmu

    2022年10月9日
    6
  • 监督学习、无监督学习、半监督学习、强化学习、自监督学习

    监督学习、无监督学习、半监督学习、强化学习、自监督学习一文读懂监督学习、无监督学习、半监督学习、强化学习四种方式 青烟王国 图:pixabay「机器人圈」导览:一般说来,训练深度学习网络的方式主要有四种:监督、无监督、半监督和强化学习。在接下来的文章中,机器人圈将逐个解释这些方法背后所蕴含的理论知识。除此之外,机器人圈将分享文献中经常碰到的术语,并提供与数学相关的更多资源。本文编译自硅谷著名的风险投资机构安德森霍洛维茨基金,作…

    2022年9月14日
    4
  • 计算机病毒防治——计算机病毒种类

    计算机病毒防治——计算机病毒种类在介绍病毒种类之前,先来介绍一些常识1、计算机病毒防治要确定安全的度,针对不同的指标设立不同的安全手段,通过以下三个方面来确定度: <1>安全威胁 <2>被保护物品的价值 <3>安全措施所要达到的目标 当攻破防御的成本大于得到数据的收益时,则系统相对来说攻击的人员较少,这时称这个系统是安全的。2、病毒是指是指编制或者在计算机程序中插入的破坏计算机功能或者毁坏数据,影响计算机使用,并且能够自我复制的一组计算机指令或者程序代码。它的根本特点是能够进行自我复制

    2022年6月4日
    51
  • js中clientWidth、scrollLeft、offsetX等宽高度和位置的用法

    js中clientWidth、scrollLeft、offsetX等宽高度和位置的用法文章目录前言一、clientWidth/clientHeight二、clientLeft/clientTop三、clientX/clientY四、scrollWidth/scrollHeight五、scrollLeft/scrollTop六、offsetWidth/offsetHeight七、offsetLeft/offsetTop八、offsetX/offsetY总结前言前端学习中会遇到的一些宽高度,位置的计算提示:以下是本篇文章正文内容,下面案例可供参考.b.

    2022年7月22日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号