从QTcpSocket读取时,QDataStream中的数据不完整

从QTcpSocket读取时,QDataStream中的数据不完整,qt,qtcpsocket,qbytearray,qtcpserver,qdatastream,Qt,Qtcpsocket,Qbytearray,Qtcpserver,Qdatastream,所以我有一个奇怪的问题,当我在qtcsocket上读取数据(QDataStream)时:一些数据似乎丢失了。bytesAvailable()函数将返回要读取的适当字节数,但QDataStream似乎并不包含所有字节 首先,这是数据的外观: bufferX始终包含768个浮点,bufferY始终包含5376个浮点。因此,我希望发送的总数据是(不包括块大小):int+768 floats+5376 floats=4+3072+21504=24580字节 现在,以下是发件人代码: void Clie

所以我有一个奇怪的问题,当我在qtcsocket上读取数据(QDataStream)时:一些数据似乎丢失了。bytesAvailable()函数将返回要读取的适当字节数,但QDataStream似乎并不包含所有字节

首先,这是数据的外观:

bufferX始终包含768个浮点,bufferY始终包含5376个浮点。因此,我希望发送的总数据是(不包括块大小):int+768 floats+5376 floats=4+3072+21504=24580字节

现在,以下是发件人代码:

void ClientSocket::serverTaskResult()
{
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_DefaultCompiledVersion);

    out << quint16(0);

    out << mServerTask->getNPoints();

    for (size_t i = 0; i < BUFFERX_SIZE; i++)
        out << mServerTask->getBufferX(i);

    for (size_t i = 0; i < BUFFERY_SIZE; i++)
        out << mServerTask->getBufferY(i);

    out.device()->seek(0);
    out << quint16(block.size() - sizeof(quint16));

    write(block);

    out << quint16(0xFFFF);
}
void ClientSocket::serverTaskResult()
{
QByteArray区块;
QDataStream out(块和QIODevice::WriteOnly);
setVersion(QDataStream::Qt_DefaultCompiledVersion);
外寻(0);
输出mNextBlockSize;
}
如果(mNextBlockSize==0xFFFF)
{
closeConnection();
打破
}
if(mTcpSocket.bytesavable()>wBufferX[i];
对于(大小i=0;i>wBufferY[i];
在>>点中;
mNextBlockSize=0;
}
}
现在,我注意到的第一件奇怪的事情是,nBytesAvailable的值总是49158,大约是我期望值的两倍。为什么我收到的字节数是预期的两倍

其次,由于我有所有这些字节可用,我希望QDataStream能够正确地填充缓冲区。然而,在315到350次浮动之后,QDataStream似乎包含不可用的数据。也就是说,wBufferX将在其前315-350个索引中定义(并更正)值,然后定义未知值。我不明白这是怎么回事,因为bytesavable()清楚地表明套接字上有将近50000字节。我错过了什么


非常感谢你的帮助!谢谢

首先,TCP是基于流的,因此您不能假设服务器的一次写入将导致客户端的一次读取——您不应该期望
mTcpSocket.bytesavable()
返回任何特定值。其次,调用
write(block)
,然后立即使用
out seek(0)间接更新
block
:我不确定在当前由
QDataStream
管理的设备上执行搜索是否有效/受支持。在读取所有内容之前,您已从读取功能中出来。当字节数小于可用字节数时,停止数据读取。我认为您应该一直阅读,直到收到所有数据或超时。您看过Qt QTcpSocket示例了吗?我应该提到,客户端的这个
recoverResult()
函数链接到
onReadyRead()
。因此,函数将被反复调用,直到
mTcpSocket.bytesavable()
为false,在这种情况下,套接字上的所有数据都应可用。
seek(0)
也像预期的那样工作,这是我在许多不同的示例中发现的。希望能澄清一点!首先,TCP是基于流的,因此您不能假设服务器的一次写入将导致客户端的一次读取——您不应该期望
mTcpSocket.bytesavable()
返回任何特定值。其次,调用
write(block)
,然后立即使用
out seek(0)间接更新
block
:我不确定在当前由
QDataStream
管理的设备上执行搜索是否有效/受支持。在读取所有内容之前,您已从读取功能中出来。当字节数小于可用字节数时,停止数据读取。我认为您应该一直阅读,直到收到所有数据或超时。您看过Qt QTcpSocket示例了吗?我应该提到,客户端的这个
recoverResult()
函数链接到
onReadyRead()
。因此,函数将被反复调用,直到
mTcpSocket.bytesavable()
为false,在这种情况下,套接字上的所有数据都应可用。
seek(0)
也像预期的那样工作,这是我在许多不同的示例中发现的。希望能澄清一点!
void TestClient::recoverResult()
{
    QDataStream in(&mTcpSocket);
    in.setVersion(QDataStream::Qt_DefaultCompiledVersion);

    float wBufferX[BUFFERX_SIZE];
    float wBufferY[BUFFERY_SIZE];
    int wNPoints;

    forever{
        if (mNextBlockSize == 0) 
        {
            qint64 nBytesAvailable = mTcpSocket.bytesAvailable();
            if (nBytesAvailable < sizeof(quint16))
                break;
            in >> mNextBlockSize;
        }

        if (mNextBlockSize == 0xFFFF) 
        {
            closeConnection();
            break;
        }

        if (mTcpSocket.bytesAvailable() < mNextBlockSize)
            break;

        for (size_t i = 0; i < BUFFERX_SIZE; i++)
            in >> wBufferX[i];

        for (size_t i = 0; i < BUFFERY_SIZE; i++)
            in >> wBufferY[i];

        in >> wNPoints;

        mNextBlockSize = 0;
    }
}