Qt C++ TCP readyread不触发或者只触发几次,readAll()丢数据,收不全数据 waitForReadyRead

背景 

QTcpSocket readyread不触发或者只触发几次,readAll()丢数据,收不全数据的原因及解决办法

最近拉手别人的项目,发现 TCP 存在很多问题,如readyread不触发或者只触发几次,readAll()丢数据,收不全数据;

附着问题的解决,这里做一下整理;先挖个坑,有赶时间填上;

一、为什么TCP会粘包, 为什么UDP 不会

TCP是面向流的的传输协议,发送端可以一次发送不定长度的数据,而接收端也可以一次提取不定长度的数据。即这种传输方式是无保护消息边界的。

UDP是面向数据报的传输协议,发送的UDP报文都被接收端视为一条消息,若消息太长被分片,UDP协议也会完成组合后才呈现在内核缓冲区;且UDP报文有消息头,对于接收端来说,易于区分处理。即这种传输方式是有保护消息边界的。

二、TCP粘包现象产生原因

TCP为了提高传输效率,会在收集到足够多数据后才一起发送;有时一条数据太长,TCP还会将数据进行拆分发生;有时发送过快,都会造成粘包。

三、解决方案:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Qt中,TCP连接的ReadyRead信号触发的条件是至少有一个字节的数据可供读取。也就是说,当QTcpSocket对象接收数据,并将其存储到了内部缓冲区中,那么当缓冲区中至少有一个字节的数据时,就会触发ReadyRead信号。 需要注意的是,ReadyRead信号是异步的,即当数据到达时,Qt会自动发出ReadyRead信号,而不是等待缓冲区填满才发出信号。这意味着,当数据到达时,可能只有一部分数据被缓冲,并且ReadyRead信号也会立即发出。 在处理ReadyRead信号时,应用程序需要根据实际情况来判断何时读取数据。在读取数据时,可以使用socket的readAll()或者readData()方法来读取全部数据或者指定长度的数据。如果希望在缓冲区中的数据达到一定数量时再读取数据,可以使用bytesAvailable()方法来获取缓冲区中的数据量,然后根据实际情况来决定是否读取数据。 以下是一个示例代码,演示了如何在判断缓冲区中的数据量是否达到一定数量后再读取数据: ```c++ QTcpSocket *socket = new QTcpSocket(this); connect(socket, &QTcpSocket::readyRead, [&]() { if (socket->bytesAvailable() >= 1024) { QByteArray data = socket->read(1024); qDebug() << "Received data:" << data; } }); ``` 在此示例代码中,创建了一个QTcpSocket对象,并连接了ReadyRead信号的槽函数。当QTcpSocket对象接收数据时,槽函数中的代码首先判断缓冲区中的数据量是否达到1024字节,如果是,则读取1024字节的数据,并输出到控制台中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恋恋西风

up up up

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值