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

C++ 从Qt中的套接字读取所有数据,c++,qt,sockets,tcp,C++,Qt,Sockets,Tcp,我正在尝试通过Qt中的网络套接字(TCP)发送图像。它可以处理较小的图像(小于8192字节),但不会处理较大的图像,因为接收端不知道它应该有多大(因此在尝试显示和显示图像之前不等待接收所有数据) 我曾尝试将数据大小添加到数组的开头,并在另一端读取数据,但在接收端得到的数字与发送前插入的数字不匹配。有人能看出我做错了什么吗 void Screenshot_controller::serializeImage(std::string fileType, QImage imageToSerialize

我正在尝试通过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);
}
void Screenshot\u controller::serializeImage(std::string fileType,QImage imageToSerialize,QByteArray*imageStream)
{
QBuffer imageBuffer(imageStream);
const char*extention=fileType.c_str();
imageToSerialize.save(&imageBuffer,扩展名);
//QString dataType=“Img”;
//imageStream->insert(0,数据类型);
qint32 size=imageStream->size();
图像流->插入(0,大小);
}
//在套接字上接收数据时使用信号调用
无效屏幕截图\u控制器::readyRead()
{
qDebug()readAll();
qint32大小=rxByteArray.at(0);
QImage图像显示;
反序列化图像(“BMP”、&imageToDisplay、rxByteArray);
显示图像(imageToDisplay);
}

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

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

如果多个平台之间的持久性不是问题。

我相信您的问题在于:

imageStream->insert(0, size);
如果查看,您将看到insert()方法的唯一实现可以将qint32作为其第二个参数,这是一个:

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

类似地,在解码步骤中,您有:

qint32 size = rxByteArray.at(0);    
同样,at()方法返回一个字节,因此无论原始图像有多大,大小值都不会大于255

解决方法是插入4个字节(因为sizeof(qint32)==4)来表示大小值。类似这样的内容将插入值(使用定义良好的endianness):

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

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

谢谢,我做了一件事,它可能不适用于int32。将尝试您的建议并发布结果。它在没有导致链接器错误的ntohl和htonl的情况下工作。在这种情况下,它们的用途是什么?它们的存在使数据以已知格式(big-endian)而不是主机CPU固有的格式发送。例如,如果没有它,运行在intel CPU上的程序将无法与运行在big-endian(即PowerPC)CPU上的程序正确通信。
qint32 beSize = *((const qint32 *) rxByteArray.constData());
qint32 size = ntohl(beSize);