2017-02-27 33 views
0

我有一個由我定義的類,比如MyClass。我想通過QTcpSocket發送該課程的一個對象。 This answer建議使用QDataStreamthis顯示如何重載運算符<<>>以實現此目的。如何使用QDataStream從QTcpSocket中讀取類對象?

我到目前爲止設法超載<<>>運營商爲QDataStream。對於發送和接收部分,我從this answerMarek R以下的方向,它回答了一個或多或少與此相同的問題。我的服務器代碼,發送MyClass對象似乎工作。但是,我無法弄清楚如何接收和格式化來自QDataStream的數據。

Marek R'sanswer

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

我不是很熟悉網絡概念,所以我可能會錯過一些微不足道的東西。

我該怎麼做?

另外,在塊的開頭髮送的quint16(0)的意義是什麼?據稱它可以作爲街區大小的指標,但它是如何做到的呢?不管塊的大小是什麼,它不一樣嗎?還是我完全誤解了它的用法?

謝謝。

+0

爲什麼不簡單地寫serializeToJson和deserializeFromJson函數?這會更簡單。 –

+0

@MherDidaryan我以爲只有字符串可以用這種方式發送。你能舉個例子,還是指點我一個資料來源? – GoodDeeds

+0

是的,你發送字節(QByteArray)。 QJsonDocument有方法toJson返回QByteArray。 –

回答

-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

+0

謝謝。我將如何實現'serializeToJson()'和'deserializeFromJson()'?此外,如果我的類有指針類型呢?這個方法可以處理它嗎? – GoodDeeds

+0

QJsonObject具有插入功能。 jsonObj.insert(「name」,this-> getName());你的指針類型也可以實現Serializable接口。 –