简体   繁体   中英

How do I read a class object from a QTcpSocket using a QDataStream?

I have a class defined by me, say MyClass . I would like to send an object of this class through a QTcpSocket . This answer suggests using a QDataStream , and this shows how the << and >> operators can be overloaded to achieve this.

I have so far managed to overload the << and >> operators for QDataStream . For the sending and receiving part, I am following directions from this answer by Marek R , which answers a question that is more or less a duplicate of this one. My server code, which sends the MyClass object seems to work. However, I am not able to figure out how to receive and format the data from the QDataStream .

From Marek R's answer ,

void SomeClass::slotReadClient() { // slot connected to readyRead signal of QTcpSocket
    QTcpSocket *tcpSocket = (QTcpSocket*)sender();
    QDataStream clientReadStream(tcpSocket);

    while(true) {
        if (!next_block_size) {
            if (tcpSocket->bytesAvailable() < sizeof(quint16)) { // are size data available
                break;
            }
            clientReadStream >> next_block_size;
        }

        if (tcpSocket->bytesAvailable() < next_block_size) {
            break;
        }
        QString str;
        clientReadStream >> str;

        next_block_size = 0;
    }
}

However, when I use this, I get an error:

error: no matching function for call to ‘QDataStream::QDataStream(QTcpSocket*&, QIODevice::OpenModeFlag)’

Based on the method of sending, I tried as follows:

    MyClass obj;
    QByteArray block;
    QDataStream rs(&block,QIODevice::ReadWrite);
    rs.setVersion(QDataStream::Qt_5_7);
    int nextblocksize = 0;
    while(true)
    {
        if(!nextblocksize)
        {
            if(socket->bytesAvailable() < sizeof(quint16))
            {
                break;
            }
            socket->read(block,socket->bytesAvailable());
            rs>>nextblocksize;
        }
        if(socket->bytesAvailable() < nextblocksize)
        {
           break;
        }
        socket->read(block,socket->bytesAvailable());
        rs>>obj;
        nextblocksize=0;
    }

However, this gives the following error:

error: conversion from ‘QByteArray’ to ‘char*’ is ambiguous
             socket->read(block,socket->bytesAvailable());
                                                        ^

For reference, the following is the code for sending, which compiles succesfully (can't check till the code for reading is working):

QTcpSocket *socket = server->nextPendingConnection();
QByteArray block;
MyClass obj(1,2.0, "Hi\n");
QDataStream ds(&block,QIODevice::ReadWrite);
ds.setVersion(QDataStream::Qt_5_7);
ds<<quint16(0)<<obj;
socket->write(block);

I am not very familiar with networking concepts, so I might be missing something trivial.

How do I do this?

In addition, what is the significance of the quint16(0) sent at the beginning of the block? It is claimed that it serves as an indicator of the size of the block, but how does it do this? Isn't it the same irrespective of what the block size is? Or have I completely misunderstood its usage?

Thank you.

If MyClass implements QJsonObject serializeToJson() and void deserializeFromJson(const QJsonObject&) you could send json representation of your class. I think it would be simpler in this way.

class Serializable
{
public:
Serializable(){}
virtual ~Serializable(){}

virtual QJsonObject serialize_to_json() = 0;
};

class Deserializable
{
public:
Deserializable(){}
virtual ~Deserializable(){}
virtual void deserialize_from_json(const QJsonObject&) = 0;
};

// MyClass implements Serializable and Deserializable
MyClass obj;

// To wrire
// construct QJsonDocument from serializeToJson
// write bytes representing the json 
// QJsonDocument::toJson() returns QByteArray
socket->write(QJsonDocument(obj.serializeToJson()).toJson());


// To read
// Construct QJsonDocument from received bytes
// QJsonDocument::fromJson(bytes).toObject returns QJsonObject
MyClass obj;
obj.deserializeFromJson(QJsonDocument::fromJson(socket->readAll()).toObject());

I omit json checking part. parsing json

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM