2017-02-27 8 views
0

私は、私が定義したクラス、例えばMyClassを持っています。このクラスのオブジェクトをQTcpSocketに送信したいと思います。 This answerは、QDataStreamを使用することを提案しており、thisは、これを達成するために<<とオペレータをどのようにオーバーロードできるかを示しています。QDataStreamを使用してQTcpSocketからクラスオブジェクトを読み取るにはどうすればよいですか?

私は今までQDataStream<<>>の演算子をオーバーロードすることができました。送受信部については、this answerからMarek 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には、QByteArrayを返すtoJsonメソッドがあります。 –

答えて

-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インタフェースを実装することもできます。 –

関連する問題