如何使用QDataStream从QTcpSocket读取类对象?

时间:2017-02-27 12:29:39

标签: c++ qt sockets qtcpsocket qdatastream

我有一个由我定义的课程,比如MyClass。我想通过QTcpSocket发送此课程的对象。 This answer建议使用QDataStreamthis显示<<>>运算符如何重载以实现此目的。

到目前为止,我设法为<<的{​​{1}}和>>运算符重载。对于发送和接收部分,我按照this answer Marek R的说明进行操作,Marek R's回答的问题或多或少与此问题重复。发送QDataStream对象的服务器代码似乎有效。但是,我无法弄清楚如何从MyClass接收和格式化数据。

来自answer {{3}},

QDataStream

然而,当我使用它时,我收到一个错误:

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;
    }
}

根据发送方法,我尝试如下:

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

但是,这会出现以下错误:

    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;
    }

供参考,以下是发送代码,成功编译(无法检查,直到阅读代码正常工作):

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

我对网络概念不太熟悉,所以我可能会遗漏一些微不足道的东西。

我该怎么做?

此外,在块开始时发送的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); 的重要性是什么?据称它可以作为块体大小的指标,但它是如何做到的?无论块大小是什么,它都不一样吗?或者我完全误解了它的用法?

谢谢。

1 个答案:

答案 0 :(得分:-1)

如果MyClass实现QJsonObject serializeToJson() and void deserializeFromJson(const QJsonObject&),您可以发送您的类的json表示。我认为这样会更简单。

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());

我省略了json检查部分。 parsing json