Я столкнулся с проблемой при отправке QByteArray
через QDataStream
,
Я создал класс для хранения сериализованного сообщения, чтобы отправить его через сокет, класс выглядит так:
#ifndef SERIALIZEDMESSAGE_H
#define SERIALIZEDMESSAGE_H
#include <QByteArray>
#include <QDataStream>
#include <QDebug>
class SerializedMessage
{
public:
SerializedMessage();
SerializedMessage(int type, QByteArray data);
friend QDataStream &operator<<(QDataStream &out, const SerializedMessage &message);
friend QDataStream &operator >>(QDataStream &in, SerializedMessage &message);
QByteArray dataArray() const;
void setDataArray(const QByteArray &dataArray);
private:
int m_type;
QByteArray m_dataArray;
};
SerializedMessage::SerializedMessage()
{
}
SerializedMessage::SerializedMessage(int type, QByteArray data)
:m_type(type), m_dataArray(data)
{
}
QByteArray SerializedMessage::dataArray() const
{
return m_dataArray;
}
void SerializedMessage::setDataArray(const QByteArray &dataArray)
{
m_dataArray = dataArray;
}QDataStream &operator<<(QDataStream &out, const SerializedMessage &message)
{
out << qint32(message.m_type);
qDebug() << "write type" << message.m_type;
out << qint32(message.m_dataArray.length());
qDebug() << "write data lenght" << message.m_dataArray.length();
int bytesWritten = out.writeRawData(message.m_dataArray.data(), message.m_dataArray.length());
qDebug() << bytesWritten << "bytes written";
qDebug() << "write data base64" << message.m_dataArray.toBase64();
return out;
}
QDataStream &operator >>(QDataStream &in, SerializedMessage &message)
{
qint32 type;
qint32 dataLength;
QByteArray dataArray;
char * tmp;
in >> type >> dataLength;
qDebug() << "read type" << type;
qDebug() << "read data lenght" << dataLength;
int bytesRead = in.readRawData(dataArray.data(), dataLength);
qDebug() << bytesRead << "bytes read";
qDebug() << "read data length" << dataArray.length();
qDebug() << "read data base64" << dataArray.toBase64();
message = SerializedMessage(type, dataArray);
return in;
}
Для проверки операторов QDataStream & operator>>
а также QDataStream &operator<<
Я создал тест-блок.
#include <QString>
#include <QtTest>
#include <QDebug>
#include "textmessage.h"#include "serializedmessage.h"class Serialization_test : public QObject
{
Q_OBJECT
public:
Serialization_test();
private Q_SLOTS:
void textMessageSerialization();
void serializedMessageFromArray();
};
Serialization_test::Serialization_test()
{
}
void Serialization_test::textMessageSerialization()
{
TextMessage txtMessage(QString("sender"), QString("message"));
SerializedMessage serialized = txtMessage.toSerializedMessage();
TextMessage deserialized = TextMessage::fromSerializedMessage(serialized);
QCOMPARE(txtMessage.sender(), deserialized.sender());
QCOMPARE(txtMessage.message(), deserialized.message());
}
void Serialization_test::serializedMessageFromArray()
{
TextMessage txtMessage(QString("sender"), QString("message"));
SerializedMessage serialized = txtMessage.toSerializedMessage();
SerializedMessage outSerialized;
QByteArray sr;
QDataStream inputStream(&sr, QIODevice::WriteOnly);
inputStream << serialized;
QDataStream outputStream(sr);
outputStream >> outSerialized;
TextMessage outText = TextMessage::fromSerializedMessage(outSerialized);
QCOMPARE(txtMessage.sender(), outText.sender());
QCOMPARE(outText.message(), outText.message());
}
QTEST_APPLESS_MAIN(Serialization_test)
#include "tst_serialization_test.moc"
Чтобы правильно запустить этот тест, вам понадобится TextMessage
учебный класс
#ifndef TEXTMESSAGE_H
#define TEXTMESSAGE_H
#include <QString>
#include <QDataStream>
#include "serializedmessage.h"
class TextMessage
{
public:
TextMessage(const QString & sender, const QString & message);
SerializedMessage toSerializedMessage();
static TextMessage fromSerializedMessage(const SerializedMessage &msg);
QString sender() const;
void setSender(const QString &sender);
QString message() const;
void setMessage(const QString &message);
private:
QString m_sender;
QString m_message;
};
#include "textmessage.h"
TextMessage::TextMessage(const QString &sender, const QString &message)
: m_sender(sender), m_message(message)
{
}
TextMessage TextMessage::fromSerializedMessage(const SerializedMessage & msg)
{
QString sender;
QString message;
QDataStream stream(msg.dataArray());
stream >> sender >> message;
TextMessage textMessge(sender, message);
return textMessge;
}
QString TextMessage::sender() const
{
return m_sender;
}
void TextMessage::setSender(const QString &sender)
{
m_sender = sender;
}
QString TextMessage::message() const
{
return m_message;
}
void TextMessage::setMessage(const QString &message)
{
m_message = message;
}SerializedMessage TextMessage::toSerializedMessage()
{
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
stream << m_sender << m_message;
SerializedMessage message(1, data);
return message;
}
#endif // TEXTMESSAGE_H
Моя проблема, когда я бегу void Serialization_test::serializedMessageFromArray()
тест зависает или не проходит с сообщением
FAIL! : Serialization_test::serializedMessageFromArray() Compared values are not the same
Actual (txtMessage.sender()): "sender"Expected (outText.sender()) : ""
Более того, отладка операторов чтения и записи показывает, что out.writeRawData(message.m_dataArray.data(), message.m_dataArray.length());
пишет то же самое количество данных, которое читается в in.readRawData(dataArray.data(), dataLength);
, Я не совсем уверен, что происходит. Буду благодарен за любую помощь
Ваша проблема в operator >>(QDataStream&, SerializedMessage&)
, Вы должны убедиться, что QByteArray
имеет правильный размер, прежде чем пытаться записать байты в него с помощью QDataStream::readRawData
:
QDataStream &operator >>(QDataStream &in, SerializedMessage &message)
{
qint32 type;
qint32 dataLength;
QByteArray dataArray;
in >> type >> dataLength;
dataArray.resize(dataLength); // <-- You need to add this line.
int bytesRead = in.readRawData(dataArray.data(), dataLength);
// Rest of function goes here.
}