繁体   English   中英

如何通过 QTcpSocket 发送带有 class 的矢量

[英]How to send vector with class by QTcpSocket

我试图从客户端向服务器发送带有 class 的向量。 数据在sockets之间发送,但是当我想将它们写入控制台时,服务器崩溃了

#include <QCoreApplication>
#include <QTcpSocket>
#include <QDataStream>
#include "data.h"

//client

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    std::vector< data > wektor;

    data asd;
    asd.setName("asd");

    wektor.push_back(asd);
    wektor.push_back(asd);

    for (data w : wektor){
        qDebug()<<w.getName();

    }


    quint16 rozmiarSampla = sizeof( wektor[0] );
    quint16 ileSampli = wektor.size();

    QTcpSocket socket;

    socket.connectToHost("127.0.0.1",9999);

    if( !socket.waitForConnected() )
        return 1;

    QDataStream stream(&socket);

    QString typ("Paczka z buforem");

    stream << typ << rozmiarSampla << ileSampli;

    stream.writeRawData( reinterpret_cast<const char*>( wektor.data() ) , rozmiarSampla * ileSampli );

    socket.flush();

    socket.waitForBytesWritten();

    return 0;
}

服务器

#include <QCoreApplication>
#include <QTcpServer>
#include <QTcpSocket>
#include <QDataStream>
#include <QScopedPointer>
#include "data.h"
#include <iostream>
#include <string.h>
//serwer
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    std::vector< data > wektor;

    QString typ;
    quint16 rozmiarSampla;
    quint16 ileSampli;

    QTcpServer serwer;
    serwer.listen(QHostAddress::AnyIPv4,9999);

    if( !serwer.waitForNewConnection(30000) )
        return 1;

    QScopedPointer<QTcpSocket> socket{ serwer.nextPendingConnection() };

    if(! socket->waitForReadyRead() )
        return 1;

    QDataStream stream(socket.data());

    stream >> typ >> rozmiarSampla >> ileSampli;

    if( rozmiarSampla == sizeof( wektor[0] ) ) {
        wektor.resize(ileSampli);
        stream.readRawData( reinterpret_cast<char*>( wektor.data() ) , rozmiarSampla * ileSampli );
    } else {
        stream.skipRawData(rozmiarSampla * ileSampli);
    }

    qDebug() << "Typ: " << typ;
    qDebug() << "RozmiarSampla: " << rozmiarSampla;
    qDebug() << "IleSampli: " << ileSampli;

    qDebug()<<wektor.size();
    qDebug()<< wektor[0].getName();
    return a.exec();
}

数据.H

#ifndef DATA_H
#define DATA_H
#include <QtCore>


class data
{
public:
    data();
    void setName(QString name);
    QString getName();
private:
    QString Name;
};

#endif // DATA_H

数据文件

#include "data.h"
#include <QtCore>

data::data()
{
    this->Name = "null";
}

void data::setName(QString name)
{
    this->Name = name;
}

QString data::getName()
{
    return this->Name;
}

尝试从数据 class 打印名称时服务器崩溃。我不明白为什么会这样,有人可以向我解释错误是什么吗? 当我试图发送一个由数据组成的向量时,例如 int,一切正常。

正如评论所建议的那样,这里的问题是 QString 不是一个简单的可复制类型。

那是什么意思? 好吧,这是一个简单的 model QString 的样子:

class QString {
public:
   // all of the methods
private:
   // QString doesn't store the data directly, it stores a pointer to the string data
    Data* data;
};

参考: https://codebrowser.dev/qt5/qtbase/src/corelib/text/qstring.h.html#979

因此,当您执行stream.writeRawData( reinterpret_cast<const char*>( wektor.data() ), rozmiarSampla * ileSampli )时,您正在复制 QString 中包含的数据......但它包含的只是一个指针,你是不复制字符串数据本身。 当然,只是指向数据的指针。 该指针在套接字的另一侧是无意义的。

那么如何解决这个问题呢? 有很多方法,但我建议专门针对您的类型使用QDataStream stream 运算符:

// In your data class header file
QDataStream& operator<<(QDataStream& stream, const data& d);
QDataStream& operator>>(QDataStream& stream, data& d);

// and in the cpp file
QDataStream& operator<<(QDataStream& stream, const data& d) {
   stream << d.getName();
   return stream;
}

QDataStream& operator>>(QDataStream& stream, data& d) {
   QString name;
   stream >> name;
   d.setName(name);
   return stream;
}

当给定一个像这样的QString时, QDataStream知道如何序列化QString 这些专门化的作用是向QDataStream展示如何序列化data 现在有了这个,您可以将您的std::vector<data>序列化为数据 stream,例如:

stream << wektor.size(); // serialize the number of instances
for (const auto& d : wektor)
   stream << d; // serialize each data instance

你可以用类似的东西反序列化它们:

size_t wektorSize;
stream >> wektorSize;

std::vector<data> wektor{wektorSize};

for (auto& d : wektor)
   stream >> d;
①如果本文未解决您的问题,请点击查看与本文相关的问题
②如果本文未解决您的问题,请向程序员专用AI小助手提问
暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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