从Qt中的套接字读取所有数据

Reading all data out of a socket in Qt

本文关键字:数据 读取 套接字 Qt      更新时间:2023-10-16

我正在尝试通过Qt中的网络套接字(TCP)发送图像。它适用于小图像(小于 8192 字节),但由于接收端不知道它应该有多大(因此在尝试显示和成像之前不会等待接收所有数据),因此不会处理较大的图像)。

我尝试将数据大小添加到数组的开头并在另一端读取它,但我在接收端得到的数字与发送前插入的数字不匹配。谁能看出我做错了什么?

void Screenshot_controller::serializeImage(std::string fileType, QImage imageToSerialize, QByteArray *imageStream)
{
    QBuffer imageBuffer(imageStream);
    const char * extention = fileType.c_str();
    imageToSerialize.save(&imageBuffer, extention);
    //QString dataType = "Img";
    //imageStream->insert(0, dataType);
    qint32 size = imageStream->size();
    imageStream->insert(0, size);
}
//Called using a signal when data is received on the socket
void Screenshot_controller::readyRead()
{
    qDebug() << "Client Reading...";
    QByteArray rxByteArray;
    rxByteArray = rxSocket->readAll();
    qint32 size = rxByteArray.at(0);    
    QImage imageToDisplay;
    deSerializeImage("BMP", &imageToDisplay, rxByteArray);
    displayImage(imageToDisplay);
}
我相信

你的问题是这样的:

imageStream->insert(0, size);

如果您查看 QByteArray 手册页,您会发现 insert() 方法的唯一可以将 qint32 作为其第二个参数的实现是:

QByteArray & insert (int i, char ch);

。这意味着您将在 QByteArray 的前面插入一个字节而不是四个字节。 这会截断该值:问题是单个字节不能容纳任何大于 255 的值,并且大多数图像的长度将超过 255 字节。

同样,在解码步骤中,您有以下内容:

qint32 size = rxByteArray.at(0);    

同样,at() 方法返回一个字节,因此无论您的原始图像有多大,您的大小值都不会大于 255。

解决此问题的方法是插入 4 个字节(因为 sizeof(qint32)==4)来代替大小值。 像这样的东西会插入值(使用明确定义的字节序):

qint32 beSize = htonl(size);
imageStream->insert(0, (const char *) &beSize, sizeof(beSize));

。然后这样的东西可以再次提取它:

qint32 beSize = *((const qint32 *) rxByteArray.constData());
qint32 size = ntohl(beSize);
没有

方法QByteArray::insert(int,uint32); 你的 uint32 将被转换为 char,你最终会得到QByteArray::insert(int,char); 你可以考虑使用

QByteArray(0,(const char *)&size,sizeof(uint32));

如果多个平台之间的字节序不是问题。