QDataStream将错误的值写入QByteArray

时间:2018-12-29 04:30:04

标签: c++ qt qbytearray qdatastream

我正在Qt中编写一个基于TCP的简单网络应用程序,并希望使用QDataStreamQByteArray通过网络发送数据。问题是,当我将数据放入QByteArray时,它们被“置零”。例如(MainWindow中与计时器超时信号连接的插槽):

void MainWindow::SendPlayer1Data(){
  QByteArray block;
  QDataStream s(&block, QIODevice::OpenModeFlag::ReadWrite);
  QString h="hello";
  s<<h;
  qDebug() << "h:        " << data;
  qDebug() << "block:    " << QString(block); // equivalent to s >> h on receiving end
  qDebug() << "block[0]: " << int(block[0]);
}

h:         "hello"
block:     ""
block[0]:  0

我一开始就收到"hello",但之后我只得到""qint32也是如此。客户端和服务器都显示QByteArray的大小为14个字节,因此QDataStream将数据写入该数组,但是使它们成为0(当我使用{{ 1}},然后使用""

2 个答案:

答案 0 :(得分:0)

这里的问题是将QString直接写到期望QByteArray的流中,请考虑以下问题

QByteArray block;
QDataStream s(&block, QIODevice::OpenModeFlag::ReadWrite);
QString h = "hello";
s << h;
qDebug() << block;

哪个输出

"\x00\x00\x00\n\x00h\x00""e\x00l\x00l\x00o"

所以数据在那里,只是那里不怎么可能有人期望它。解决此问题的最简单方法是从使用UTF8(或您选择的其他编码)编码的字符串创建QByteArray。这可以随时随地完成,

QByteArray block;
QDataStream s(&block, QIODevice::OpenModeFlag::ReadWrite);
QString h = "hello";
QByteArray data(h.toUtf8(), 5);
s << data;
qDebug() << block;

哪个输出

"\x00\x00\x00\x05hello"

因为通过QByteArray发送此QDataStream时,数组的长度和3个NULL字符被附加了-NULL字符在那里,如果缓冲区是大于一个相对较小的5(您可以通过传递一个较大的值来进行测试-256的最小代表是最典型的-作为QByteArray构造函数中的第二个参数,因为这是缓冲区长度)。但是,如果您尝试从QString开头的s >> h显式构造NULL(就像QByteArray一样),则会创建一个空字符串。要对此进行更正,您可以使用QByteArray::remove()这样删除前4个字节

QByteArray block;
QDataStream s(&block, QIODevice::OpenModeFlag::ReadWrite);
QString h = "hello";
QByteArray data(h.toUtf8());
s << data;
qDebug() << QString::fromUtf8(block.remove(0, 4));

哪个输出

"hello"

完整示例

#include <qbytearray.h>
#include <qdatastream.h>
#include <qdebug.h>

int main() {
  QByteArray block;
  QDataStream s(&block, QIODevice::OpenModeFlag::ReadWrite);
  QString h = "hello";
  QByteArray data(h.toUtf8());
  s << data;
  qDebug() << QString::fromUtf8(block.remove(0, 4));
}

答案 1 :(得分:0)

好,我知道了。 问题不是const regex = /^[^\t\n][\w\W]*?$/gm; const str = `Explore results with the Tools below. Replace & List output custom results. Details lists capture groups. Explain describes your expression in plain English. something something2 Hey how are you is this what you wanted to achieve string with tab inside hello hello end v v `; let m; while ((m = regex.exec(str)) !== null) { // This is necessary to avoid infinite loops with zero-width matches if (m.index === regex.lastIndex) { regex.lastIndex++; } // The result can be accessed through the `m`-variable. m.forEach((match, groupIndex) => { console.log(`Found match, group ${groupIndex}: ${match}`); }); }或套接字,因为如QByteArray所述,数据在那里。 问题出在客户端的@William Miller上-我决定每次调用负责接收数据的插槽时都创建一个新的QDataStream对象。这样,我就可以轻松地将数据打包到QDataStream中,每次发送和接收。 用于接收以下内容的客户端功能:

QByteArray

并将数据解压缩为变量:

void ClientTcpHelper::ReceivePacket(){

if(socket.waitForReadyRead(20)){

    //qDebug()<<"Packet: "<<socket.peek(30)<<endl;
    qDebug()<<"Receiving packet!"<<endl;

    Data=socket.readAll();
    emit DataReceived();


}
else{
    //qDebug()<<"Failed to receive packet!"<<endl;

}}

h,a和b是类的成员。

不幸的是,我无法解释为什么void ClientTcpHelper::UnpackData(){ stream=new QDataStream (&this->Data,QIODevice::OpenModeFlag::ReadWrite); *stream>>h>>a>>b; Data.clear(); delete stream;} 每次都需要销毁,以便从一开始就按需要处理数据。