Russian Qt Forum
Ноябрь 23, 2024, 10:20 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: QVector в QDataStream для передачи по сети! Помогите  (Прочитано 20200 раз)
lolbla2
Гость
« Ответ #15 : Февраль 06, 2012, 19:11 »



blockSize по вашему что? - если честно сам не понимаю что делает вот этот кусок кода:

Код:
    if (blockSize == 0) {
        if (sockets->bytesAvailable() < (int)sizeof(quint32))
            continue;
        in >> blockSize;
    }
 

Я взял егто из примера про fortune client/server

Записан
lolbla2
Гость
« Ответ #16 : Февраль 06, 2012, 19:42 »

Цитировать
В Qt есть такая вещь как  Q_DECLARE_METATYPE
Код:
struct MyStruct
 {
     int i;
     ...
 };
 Q_DECLARE_METATYPE(MyStruct)



Это позволяет запихивать и доставать свои типы из QVariant ИМХО так будет попроще делать) чем структуры в сокет пихать


Я пробовал рассмотреть такой вариант, но да можно запихнуть тогда свой класс в обёртку QVariant, но возникает проблема что QVariant не запихнуть в QDataStream ибо нужно определить операторы << и >> для QVariant
Записан
lolbla2
Гость
« Ответ #17 : Февраль 06, 2012, 19:50 »

challenge accepted  Показает язык
Код:
int main(int argc,char** argv){
    QApplication app(argc,argv);

    promp p1,p2,p3,p4,p5;
    p1.val1=1;
    p1.val2=10;
    p1.val3=true;

    p2.val1=2;
    p2.val2=20;
    p2.val3=true;

    p3.val1=3;
    p3.val2=30;
    p3.val3=true;

    p4.val1=4;
    p4.val2=40;
    p4.val3=true;

    p5.val1=5;
    p5.val2=50;
    p5.val3=true;

    QVector<promp> players;

    players.append(p1);
    players.append(p2);
    players.append(p3);
    players.append(p4);
    players.append(p5);


    QFile f("temp.t");
    {
        f.open(QIODevice::WriteOnly);
        f.resize(0);
        QDataStream s(&f);
        s<<players;
        f.close();
    }


    p1.val1=0; p1.val2=0; p1.val3=false;
    p2.val1=0; p2.val2=0; p2.val3=false;
    p3.val1=0; p3.val2=0; p3.val3=false;
    p4.val1=0; p4.val2=0; p4.val3=false;
    p5.val1=0; p5.val2=0; p5.val3=false;
    players.clear();

    {
        f.open(QIODevice::ReadOnly);
        QDataStream s(&f);
        s>>players;
        f.close();
        for(int i=0; i<players.size();i++)
        qWarning()<<"p"<<i<<"\t"<< players.at(i).val1 << players.at(i).val2 << players.at(i).val3;
    }

    return 1;
}
Код:
Запускается D:\qt\projects\LIC_NEW\release\CRYPTER.exe...
p 0 1 10 true
p 1 2 20 true
p 2 3 30 true
p 3 4 40 true
p 4 5 50 true
D:\qt\projects\LIC_NEW\release\CRYPTER.exe завершился с кодом 1

Методы записи чтения те же. Структурка та же.

Хмм забавно таки.... Создал те же самые проверки для своей структуры всё работает. А вот в приложении где сервер пишу почему-то ошибки вылезают как на 2 картинке в 1 сообщении в теме... Что это может быть?((
Записан
lolbla2
Гость
« Ответ #18 : Февраль 06, 2012, 20:05 »

Оо выяснил, с файлами работает, с сокетами не пашет, ошибки вылезают (( вот попробуй сам))
Записан
Orfus
Гость
« Ответ #19 : Февраль 07, 2012, 10:47 »

Никакой зависимости файл или сокет нету. Ты определяешь как пихать в QDataStream, а уже с чем он связан дело десятое. Я не ванга, ошибки удалённо вылетающие не вижу.


client.срр
Код:
#include <QtCore>
#include <QApplication>
#include <QtNetwork>
#include "client.h"

QDataStream &operator>>(QDataStream &in, promp &inp){
    in>>inp.val1;
    in>>inp.val2;
    in>>inp.val3;
    return in;
}
QDataStream &operator>>(QDataStream &in, promp *inp){
    in>>inp->val1;
    in>>inp->val2;
    in>>inp->val3;
    return in;
}
QDataStream &operator<<(QDataStream &out, const promp &inp){
    out<<inp.val1<<inp.val2;
    out<<inp.val3;
    return out;
}
QDataStream &operator<<(QDataStream &out, const promp *inp){
    out<<inp->val1<<inp->val2;
    out<<inp->val3;
    return out;
}


int main(int argc,char** argv){
    QApplication app(argc,argv);

    promp p1,p2,p3,p4,p5;
    p1.val1=1;
    p1.val2=10;
    p1.val3=true;

    p2.val1=2;
    p2.val2=20;
    p2.val3=true;

    p3.val1=3;
    p3.val2=30;
    p3.val3=true;

    p4.val1=4;
    p4.val2=40;
    p4.val3=true;

    p5.val1=5;
    p5.val2=50;
    p5.val3=true;

    QVector<promp> players;

    players.append(p1);
    players.append(p2);
    players.append(p3);
    players.append(p4);
    players.append(p5);


    QTcpSocket sock;
    sock.connectToHost("localhost",3474);
    sock.waitForConnected(10000);
    if(sock.state()!=QAbstractSocket::UnconnectedState){


        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_4_7);
        //выделяешь место в начале соощения размером 4 байта
        out << (quint32)0;
        //записываешь данные
        out << players;
        //возвращаешься в начало на те 4 байта
        out.device()->seek(0);
        //записываешь размер данных (тот самый BlockSize)
        out << (quint32)(block.size() - sizeof(quint32));

        //for(int i=0; i<sockets.size(); i++)  sockets->write(block);
        sock.write(block);//высылаешь
        sock.waitForBytesWritten();
        sock.flush();



        qWarning()<<"ok"<<block.size();
    }
    else{
        qWarning()<<"cannot connect";
    }

    sock.close();

    return 1;
}
client.h
Код:
#ifndef CLIENT_H
#define CLIENT_H
struct promp{
public:
    int  val1;
    int  val2;
    bool val3;
};
#endif // CLIENT_H


server.h
Код:
#ifndef SERVER_H
#define SERVER_H
#include <QtNetwork>
struct promp{
public:
    int  val1;
    int  val2;
    bool val3;
};



class Serv:public QObject{
    Q_OBJECT
public:
    Serv(QObject* parent=0):QObject(parent){
        QTcpServer *s=new QTcpServer(this);
        s->listen(QHostAddress::Any,3474);
        connect(s,SIGNAL(newConnection()),this,SLOT(nc()));

    }
public slots:
    void nc(){
        QTcpSocket *so=((QTcpServer*)sender())->nextPendingConnection();
        connect(so,SIGNAL(readyRead()),this,SLOT(read()));

    }
    void read(){
        QTcpSocket *so=(QTcpSocket*)sender();
        QByteArray arr=so->readAll();

        qWarning()<<arr.size();

    }


};
#endif // SERVER_H
server.cpp
Код:
#include <QApplication>
#include <QtNetwork>
#include <QtCore>
#include "server.h"
QDataStream &operator>>(QDataStream &in, promp &inp){
    in>>inp.val1;
    in>>inp.val2;
    in>>inp.val3;
    return in;
}
QDataStream &operator>>(QDataStream &in, promp *inp){
    in>>inp->val1;
    in>>inp->val2;
    in>>inp->val3;
    return in;
}
QDataStream &operator<<(QDataStream &out, const promp &inp){
    out<<inp.val1<<inp.val2;
    out<<inp.val3;
    return out;
}
QDataStream &operator<<(QDataStream &out, const promp *inp){
    out<<inp->val1<<inp->val2;
    out<<inp->val3;
    return out;
}


int main(int argc,char** argv){
    QApplication app(argc,argv);
    Serv *s= new Serv(0);


    return app.exec();
}


вывод клиента
Код:
Запускается D:\qt\projects\LIC_NEW\release\CRYPTER.exe...
ok 53
D:\qt\projects\LIC_NEW\release\CRYPTER.exe завершился с кодом 1

Запускается D:\qt\projects\LIC_NEW\release\CRYPTER.exe...
ok 53
D:\qt\projects\LIC_NEW\release\CRYPTER.exe завершился с кодом 1
вывод сервера
Код:
Запускается D:\qt\projects\serv\debug\serv.exe...
53
53
Программа неожиданно завершилась.
D:\qt\projects\serv\debug\serv.exe завершился с кодом 62097
« Последнее редактирование: Февраль 07, 2012, 10:49 от Orfus » Записан
lolbla2
Гость
« Ответ #20 : Февраль 07, 2012, 11:23 »

Никакой зависимости файл или сокет нету. Ты определяешь как пихать в QDataStream, а уже с чем он связан дело десятое. Я не ванга, ошибки удалённо вылетающие не вижу.

Вот сам удивился вроде нет разницы что файл, что сокеты, но почему-то с файлами норм, а с сокетами нет. ПОлучается у тебя заработало с сокетами? Кстати ты же их в QByteArray считал а как его также в вектор засунуть на сервере? по идее надо использловать >> , а оно чот не пашет((
« Последнее редактирование: Февраль 07, 2012, 11:26 от lolbla2 » Записан
Orfus
Гость
« Ответ #21 : Февраль 07, 2012, 11:27 »

*facepalm* выше 2 рабочих примера.
Тут вообще никакой связи с сокетами нет. Ты пишешь через QDataStream в QByteArray. В сокет ты толкаешь уже готовый QByteArray. Код и(или) ошибки демонстрировать то будешь или секрет фирмы? Смеющийся
Записан
lolbla2
Гость
« Ответ #22 : Февраль 07, 2012, 11:32 »

*facepalm* выше 2 рабочих примера.
Тут вообще никакой связи с сокетами нет. Ты пишешь через QDataStream в QByteArray. В сокет ты толкаешь уже готовый QByteArray. Код и(или) ошибки демонстрировать то будешь или секрет фирмы? Смеющийся

Ошибки, я ж говорю такие как на 2 картинке в самом первом посте((
Записан
Orfus
Гость
« Ответ #23 : Февраль 07, 2012, 11:35 »

Те 4 метода с QDataStream перенеси в файл где у тебя запись\чтение из сокета идут.

Второй вариант напиши перед теми 4мя функциями inline и запихни в общий хедер.
« Последнее редактирование: Февраль 07, 2012, 11:42 от Orfus » Записан
lolbla2
Гость
« Ответ #24 : Февраль 07, 2012, 12:46 »

Те 4 метода с QDataStream перенеси в файл где у тебя запись\чтение из сокета идут.

Второй вариант напиши перед теми 4мя функциями inline и запихни в общий хедер.

Огромное спасибо! Всё заработало как надо))
Записан
KrupaKarlo
Гость
« Ответ #25 : Февраль 07, 2012, 13:54 »


Цитировать
А разве Q_DECLARE_METATYPE(MyStruct) позволит запихнуть в QDataStream?

в датастрим можно запихнуть QVariant в который будет запихан MyStruct

Записан
lolbla2
Гость
« Ответ #26 : Февраль 07, 2012, 14:34 »


Цитировать
А разве Q_DECLARE_METATYPE(MyStruct) позволит запихнуть в QDataStream?

в датастрим можно запихнуть QVariant в который будет запихан MyStruct



НЕЛЬЗЯ в датастрим  запихнуть QVariant потому что для QVariant не определены операторы << и >> !
Записан
Orfus
Гость
« Ответ #27 : Февраль 07, 2012, 15:15 »


Цитировать
А разве Q_DECLARE_METATYPE(MyStruct) позволит запихнуть в QDataStream?

в датастрим можно запихнуть QVariant в который будет запихан MyStruct



НЕЛЬЗЯ в датастрим  запихнуть QVariant потому что для QVariant не определены операторы << и >> !
o rly?
Код:
#include <QtCore>
#include <QApplication>

struct promp{
    int val1;
    int val2;
    bool val3;
};
Q_DECLARE_METATYPE(promp)

int main(int argc,char** argv){
    QApplication app(argc,argv);

    qRegisterMetaType<promp>("promp");

    promp p1;
    p1.val1=1;
    p1.val2=10;
    p1.val3=false;
    QVariant v=qVariantFromValue(p1);

    QFile f("t.temp");
    f.open(QIODevice::WriteOnly);
    f.resize(0);
    QDataStream st(&f);
    st<<v;
    f.close();

    return 1;
}
UPD
выкидывает
Код:
QVariant::save: unable to save type 258.
Немножко гугла выдало необходимость делать qRegisterMetaTypeStreamOperators<MyClass>("MyClass"); и увы таки описывать работу с QDataStream в обязательном порядке.




Но мне всё это не нравится по одной причине. и QVector и QVariant жрут больше ресурсов, чем нужно для задачи.
Я бы пихал ручками
Код:
out<<p1.val1<<p1.val2<<p1.val3;
а вначале ценной части сообщения писал кол-во структур приходящих.
« Последнее редактирование: Февраль 07, 2012, 16:05 от Orfus » Записан
lolbla2
Гость
« Ответ #28 : Февраль 07, 2012, 16:15 »



Цитировать
o rly?
Код:
#include <QtCore>
#include <QApplication>

struct promp{
    int val1;
    int val2;
    bool val3;
};
Q_DECLARE_METATYPE(promp)

int main(int argc,char** argv){
    QApplication app(argc,argv);

    qRegisterMetaType<promp>("promp");

    promp p1;
    p1.val1=1;
    p1.val2=10;
    p1.val3=false;
    QVariant v=qVariantFromValue(p1);

    QFile f("t.temp");
    f.open(QIODevice::WriteOnly);
    f.resize(0);
    QDataStream st(&f);
    st<<v;
    f.close();

    return 1;
}
UPD
выкидывает
Код:
QVariant::save: unable to save type 258.
Немножко гугла выдало необходимость делать qRegisterMetaTypeStreamOperators<MyClass>("MyClass"); и увы таки описывать работу с QDataStream в обязательном порядке.




Но мне всё это не нравится по одной причине. и QVector и QVariant жрут больше ресурсов, чем нужно для задачи.
Я бы пихал ручками
Код:
out<<p1.val1<<p1.val2<<p1.val3;
а вначале ценной части сообщения писал кол-во структур приходящих.

Я же говорил надо определить операторы <<  и >>, но я же не знал что их можно определить так просто с помощью  qRegisterMetaTypeStreamOperators<MyClass>("MyClass");

Кстати а для чего нужно
Код:
qRegisterMetaType<promp>("promp");
?
 Разве макрос
Код:
Q_DECLARE_METATYPE(promp)
не регистрирует тип для QVariant?
Возможно много ресурсов жрёт но писать out<<p1.val1<<p1.val2<<p1.val3; а у меня так как ты видел 11 полей в структуре слишком не читабельный код делает. Наверно, конечно, я неправильно подхожу к данной задаче, но мне пока бы сделать так чтобы работало вообще и не важно сколько ресурсов жрёт, об оптимальности подумаю позже. Особенно мне понравилась идея сделать передачу и приём данных в отдельном потоке. Может сделаю позже, а пока хочу чтобы вообще это хотя бы так работало.

P.S. Orfus я вижу ты опытный программист, респект xD. Где и как учился прогать ?)))
Записан
Orfus
Гость
« Ответ #29 : Февраль 07, 2012, 16:50 »

...
Я же говорил надо определить операторы <<  и >>, но я же не знал что их можно определить так просто с помощью  qRegisterMetaTypeStreamOperators<MyClass>("MyClass");
Их в любом случае, будешь ты использовать QVariant или QVector необходимо описывать.

Кстати а для чего нужно
Код:
qRegisterMetaType<promp>("promp");
?
 Разве макрос
Код:
Q_DECLARE_METATYPE(promp)
не регистрирует тип для QVariant?
Первый регистрирует, второй декларирует. В доках должно быть описано что делает каждый из них, но нужны оба. Я с ними сталкивался только когда свои типы в сигнал\слоты добавлял.

Возможно много ресурсов жрёт но писать out<<p1.val1<<p1.val2<<p1.val3; а у меня так как ты видел 11 полей в структуре слишком не читабельный код делает. Наверно, конечно, я неправильно подхожу к данной задаче, но мне пока бы сделать так чтобы работало вообще и не важно сколько ресурсов жрёт, об оптимальности подумаю позже. Особенно мне понравилась идея сделать передачу и приём данных в отдельном потоке. Может сделаю позже, а пока хочу чтобы вообще это хотя бы так работало.

P.S. Orfus я вижу ты опытный программист, респект xD. Где и как учился прогать ?)))

Я не то чтобы опытный, просто сеть на Qt уже полгода ковыряю и шишечек понабил уже себе. Учился большей частью сам по книжкам и примерам. Сейчас как раз место работы меняю чтоб на новом подучится у старших программировать правильно, а не индусокодить.
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.054 секунд. Запросов: 21.