Qt 发送端一次发送多条数据,但接收端只接收一次总的数据
在发送端使用
TcpSocket向接收端同时发送多条数据,但是接收端只能收到总的数据。网络上称这种情况为 ”粘包“,虽然 TcpSocket 的传输方式为数据流,但用“粘包”这一名词形容这种现象还是很贴切的。


产生粘包的原因
TCP基于数据流传输,Write()和Read()的次数不固定,可能在读之前就合并了。粘包的解决方法(自定义包头结构)
模拟电报的发送方式,将需要发送的数据打包成数据包,数据包分成包头和包体,包头表示需要接收数据的大小,包体为需要发送的数据。
发送端发出数据包,接收端会从缓冲区接收数据包,先找到包头,在根据包头的大小确定包体数据。
这里给出的代码为如何设置数据包,具体的发送与接收,可看这一篇博客 Qt—处理TCP粘包
1 发送端
QByteArray block; QDataStream out(&block,QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_9); //设置数据流的版本,发送端和客户端版本需要一致 out << (quint16)0; // 设置包头 out << "22222"; //需要发送的数据 out.device()->seek(0); out << (quint16)(block.size() - sizeof(quint16)); // 确定包体的大小 tcpSocket->write(block);2 接收端
//这里需要注意 blockSize 的初始化问题,blockSize 为 quint16 类型的全局变量 //message 可为QString,也可为 QByteArray QTcpSocket *sock = (QTcpSocket*) sender(); QDataStream in(sock); in.setVersion(QDataStream::Qt_5_9); //刚开始接收数据 if(blockSize == 0) { //判断接收的数据是否大于两个字节,也是数据大小信息所占空间 //如果是则保存到 blockSize 中,否则继续接收数据 if(sock->bytesAvailable() < (int)sizeof(quint16)) return ; in >> blockSize; } //如果没有得到全部的数据,则返回,继续接收数据 if(sock->bytesAvailable() < blockSize) return ; //将接收到的数据存在变量中 in >> message;如果发送端一次发送 n 条数据,那需要设置接收端读 n 次。
对于接收端
socket,正确的处理粘包问题的方式是 :先将缓冲区中的数据读取出来,再拆包,而不是边读取边分包。
网上给出了处理方式都是采用自定义包头结构,但是,依旧没有解决一发一读的问题,还是多次发送,一次读取,只是能把数据分开。
参考博客:
版权声明:本文为weixin_46870692原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。