Russian Qt Forum

Qt => Работа с сетью => Тема начата: lolbla2 от Февраль 06, 2012, 12:35



Название: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 06, 2012, 12:35
Нужно передать вектор моей структуры Input, то есть QVector <Input *> data ; даже не знаю лучше ссылку или без ссылки, т.е. QVector <Input *> data или QVector <Input > data. Ну не важно и так и так не работает((( вообщем структура имеет следующий вид:
struct Input
{
    bool startflag;
    int player;
    bool t_dead;
    int t_dir;
    int t_posx;
    int t_posy;
    int t_movex;
    int t_movey;
    int b_posx;
    int b_posy;
    int b_dir;
};

QDataStream &operator<<(QDataStream &out, const Input &inp)
{
    out<<(quint32)inp.b_dir<<(quint32)inp.b_posx<<(quint32)inp.b_posy<<
         (quint32)inp.player<<(quint32)inp.t_dir<<(quint32)inp.t_movex<<
         (quint32)inp.t_movey<<(quint32)inp.t_posx<<(quint32)inp.t_posy<<
         inp.startflag<<inp.t_dead;
    return out;
}
QDataStream &operator>>(QDataStream &in, Input &inp)
{
    quint32 player;
    quint32 t_dir;
    quint32 t_posx;
    quint32 t_posy;
    quint32 t_movex;
    quint32 t_movey;
    quint32 b_posx;
    quint32 b_posy;
    quint32 b_dir;
    bool t_dead;
    bool startflag;
    in>>b_dir>>b_posx>>b_posy>>player>>t_dir>>t_movex>>t_movey>>t_posx>>t_posy>>startflag>>t_dead;
    inp.b_dir=b_dir;
    inp.b_posx=b_posx;
    inp.b_posy=b_posy;
    inp.player=player;
    inp.t_dir=t_dir;
    inp.t_movex=t_movex;
    inp.t_movey=t_movey;
    inp.t_posx=t_posx;
    inp.t_posy=t_posy;
    inp.startflag=startflag;
    inp.t_dead=t_dead;
    return in;
}

пытаюсь принимать :

void Widget::OnReceiveData()
{
    QMessageBox::information(this,"data received!","data received from client!");
    for(int i=0; i<sockets.size(); i++)
    {
        QDataStream in(sockets);
    in.setVersion(QDataStream::Qt_4_7);

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

    if (sockets->bytesAvailable() < blockSize)
        continue;
    in>> data; // здесь ошибка

    }
}


(http://image.kz/img/16/162c65e645bb183794ceb5b8a4c0f318.png)
что он тут ругается типо не может найти операторы << и >> если они есть не пойму((

а если пытаюсь отправить:
void Widget::SendData()
{
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_7);
//! [4] //! [6]
    out << (quint32)0;
    out << data;
    out.device()->seek(0);
    out << (quint32)(block.size() - sizeof(quint32));
    for(int i=0; i<sockets.size(); i++)
    {
        sockets->write(block);
    }

}

то другие ошибки возникают:
(http://image.kz/img/93/93948cd927aed9dd6b547c87d94da2ed.png)


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Orfus от Февраль 06, 2012, 12:52
1)пользуйтесь тегам кода
2)В слоте void Widget::OnReceiveData() вместо поисков нужного сокета можно использовать
Код:
    QTcpSocket* TCPSocket = (QTcpSocket*)sender();
    QDataStream in(TCPSocket);
Рекомендовал бы даже если подключений много, для каждого подключения хранить blockSize отдельно.
Если машины не в локальной сети, неплохо бы повторить OnReceiveData() в конце метода OnReceiveData(), ибо новые пакеты придут, а сигнала не будет.

3)Про стрим не подскажу, но объясните мне кто нибудь зачем делать отдельный метод? Что мешает делать
Код:
in>>data.b_dir;
in>>data.b_posx;
in>>data.b_posy;
in>>data.player;
in>>data.t_dir;
in>>data.t_movex;
in>>data.t_movey;
in>>data.t_posx;
in>>data.t_posy;
in>>data.startflag;
in>>data.t_dead;

4) Делать сеть внутри GUI потока черевато.
5) после прочтения данных, стоило бы сделать blockSize=0;


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 06, 2012, 13:14
1)пользуйтесь тегам кода
2)В слоте void Widget::OnReceiveData() вместо поисков нужного сокета можно использовать
Код:
    QTcpSocket* TCPSocket = (QTcpSocket*)sender();
    QDataStream in(TCPSocket);
Рекомендовал бы даже если подключений много, для каждого подключения хранить blockSize отдельно.
Если машины не в локальной сети, неплохо бы повторить OnReceiveData() в конце метода OnReceiveData(), ибо новые пакеты придут, а сигнала не будет.

3)Про стрим не подскажу, но объясните мне кто нибудь зачем делать отдельный метод? Что мешает делать
Код:
in>>data.b_dir;
in>>data.b_posx;
in>>data.b_posy;
in>>data.player;
in>>data.t_dir;
in>>data.t_movex;
in>>data.t_movey;
in>>data.t_posx;
in>>data.t_posy;
in>>data.startflag;
in>>data.t_dead;

4) Делать сеть внутри GUI потока черевато.
5) после прочтения данных, стоило бы сделать blockSize=0;

Код:
QVector < Input *> data;
- такой тип имеет, поэтому думаю не получится как Вы имели в виду, мы ведь не знаем размер вектора который придёт по сети
Почему чревата сеть внутри GUI?


Насчёт тегов сори, я недавно на вашем форуме


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Orfus от Февраль 06, 2012, 13:19
GUI будет провисать в моменты объемных приёмов\передач. Я не имею ни малейшего понятия насколько велик поток трафика в ваших приложениях, но если он объёмный стоит задуматься  о классе для сети и отдельном потоке.


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Странник от Февраль 06, 2012, 13:26
по-моему операторы >> и << у вас объявлены для Input, а передавать вы пытаетесь Input*.


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 06, 2012, 13:34
GUI будет провисать в моменты объемных приёмов\передач. Я не имею ни малейшего понятия насколько велик поток трафика в ваших приложениях, но если он объёмный стоит задуматься  о классе для сети и отдельном потоке.


Ну вообще делаю игру танчики на подобии дендевской. Максимум 6 игроков. Как Вы уже наверно догадались структура для передачи данных имеет вид:
Код:
struct Input
{
    bool startflag;
    int player;
    bool t_dead;
    int t_dir;
    int t_posx;
    int t_posy;
    int t_movex;
    int t_movey;
    int b_posx;
    int b_posy;
    int b_dir;
};
Т.е. QVector из таких структур размерности количества игроков.

Серверное приложение отдельно.

Клиент когда сдвинул танчик или стрельнул, то серверу приходят от него данные и сервер в свою очередь всем игрокам рассылает данные о всех танчиках, но каждому не шлёт егошние данные, то есть игроку 1 шлёт данные о игроках 2,3,4,5,6. Игроку 2 данные о игроках 1,3,4,5,6 и т д.


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 06, 2012, 13:40
по-моему операторы >> и << у вас объявлены для Input, а передавать вы пытаетесь Input*.
пробовал менять на * и без не помогало


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Orfus от Февраль 06, 2012, 13:42
Всё же я убеждён что в QDataStream &operator>>(QDataStream &in, Input &inp) 38 байт жрутся напрасно.

p.s. представил уже как написать wallhack и speedhack  8)


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 06, 2012, 13:50
Всё же я убеждён что в QDataStream &operator>>(QDataStream &in, Input &inp) 38 байт жрутся напрасно.




Возможно но это пока ерунда по сравнению с глобальной проблемой - почему не пашут  эти перегруженные операторы))


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Orfus от Февраль 06, 2012, 14:28
.h
Код:
struct promp{
public:
    int  val1;
    int  val2;
    bool val3;
};
.cpp
Код:
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;
    promp *p2= new promp();
    p1.val1=1;p2->val1=2;
    p1.val2=10;p2->val2=20;
    p1.val2=true;p2->val3=false;


    QFile f("temp.t");
    {
        f.open(QIODevice::WriteOnly);
        f.resize(0);
        QDataStream s(&f);
        s<<p1;
        f.close();
    }
    {
        f.open(QIODevice::ReadOnly);
        QDataStream s(&f);
        s>>p2;
        f.close();
        qWarning()<<"p1 write, p2 read\t"<< p2->val1 << p2->val2 << p2->val3;
    }
    {
        p2->val1=2;p2->val2=20;p2->val3=false;
        f.open(QIODevice::WriteOnly);
        f.resize(0);
        QDataStream s(&f);
        s<<p2;
        f.close();
    }

    {
        f.open(QIODevice::ReadOnly);
        QDataStream s(&f);
        s>>p1;
        f.close();
        qWarning()<<"p2 write, p1 read\t"<< p1.val1 << p1.val2 << p1.val3;
    }

    return 1;
}
Сравнивай, подстраивай под себя. У меня работают

Код:
Запускается D:\qt\projects\LIC_NEW\release\CRYPTER.exe...
p1 write, p2 read 1 1 true
p2 write, p1 read 2 20 false
D:\qt\projects\LIC_NEW\release\CRYPTER.exe завершился с кодом 1


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Orfus от Февраль 06, 2012, 14:31
Но всё равно, в отсутствии чего то глобального в структурке считаю что ты просто захламляешь стек вызовов (http://ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%B5%D0%BA_%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%BE%D0%B2).


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 06, 2012, 14:59
Но всё равно, в отсутствии чего то глобального в структурке считаю что ты просто захламляешь стек вызовов (http://ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%B5%D0%BA_%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%BE%D0%B2).

а попробуй засунь свою структуру в QVector и отправь её в QDataStream, а потом вытащи оттуда будет ли работать?


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Orfus от Февраль 06, 2012, 15:20
challenge accepted  :P
Код:
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

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


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: KrupaKarlo от Февраль 06, 2012, 16:14
GUI будет провисать в моменты объемных приёмов\передач. Я не имею ни малейшего понятия насколько велик поток трафика в ваших приложениях, но если он объёмный стоит задуматься  о классе для сети и отдельном потоке.


Ну вообще делаю игру танчики на подобии дендевской. Максимум 6 игроков. Как Вы уже наверно догадались структура для передачи данных имеет вид:
Код:
struct Input
{
    bool startflag;
    int player;
    bool t_dead;
    int t_dir;
    int t_posx;
    int t_posy;
    int t_movex;
    int t_movey;
    int b_posx;
    int b_posy;
    int b_dir;
};
Т.е. QVector из таких структур размерности количества игроков.

Серверное приложение отдельно.

Клиент когда сдвинул танчик или стрельнул, то серверу приходят от него данные и сервер в свою очередь всем игрокам рассылает данные о всех танчиках, но каждому не шлёт егошние данные, то есть игроку 1 шлёт данные о игроках 2,3,4,5,6. Игроку 2 данные о игроках 1,3,4,5,6 и т д.

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

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


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Orfus от Февраль 06, 2012, 16:43
...
Это позволяет запихивать и доставать свои типы из QVariant ИМХО так будет попроще делать) чем структуры в сокет пихать


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

P.S.
.... мы ведь не знаем размер вектора который придёт по сети ....

blockSize по вашему что?


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 06, 2012, 19:11


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

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

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



Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 06, 2012, 19:42
Цитировать
В Qt есть такая вещь как  Q_DECLARE_METATYPE
Код:
struct MyStruct
 {
     int i;
     ...
 };
 Q_DECLARE_METATYPE(MyStruct)



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


Я пробовал рассмотреть такой вариант, но да можно запихнуть тогда свой класс в обёртку QVariant, но возникает проблема что QVariant не запихнуть в QDataStream ибо нужно определить операторы << и >> для QVariant


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 06, 2012, 19:50
challenge accepted  :P
Код:
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 сообщении в теме... Что это может быть?((


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 06, 2012, 20:05
Оо выяснил, с файлами работает, с сокетами не пашет, ошибки вылезают (( вот попробуй сам))


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Orfus от Февраль 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


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 07, 2012, 11:23
Никакой зависимости файл или сокет нету. Ты определяешь как пихать в QDataStream, а уже с чем он связан дело десятое. Я не ванга, ошибки удалённо вылетающие не вижу.

Вот сам удивился вроде нет разницы что файл, что сокеты, но почему-то с файлами норм, а с сокетами нет. ПОлучается у тебя заработало с сокетами? Кстати ты же их в QByteArray считал а как его также в вектор засунуть на сервере? по идее надо использловать >> , а оно чот не пашет((


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Orfus от Февраль 07, 2012, 11:27
*facepalm* выше 2 рабочих примера.
Тут вообще никакой связи с сокетами нет. Ты пишешь через QDataStream в QByteArray. В сокет ты толкаешь уже готовый QByteArray. Код и(или) ошибки демонстрировать то будешь или секрет фирмы? ;D


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 07, 2012, 11:32
*facepalm* выше 2 рабочих примера.
Тут вообще никакой связи с сокетами нет. Ты пишешь через QDataStream в QByteArray. В сокет ты толкаешь уже готовый QByteArray. Код и(или) ошибки демонстрировать то будешь или секрет фирмы? ;D

Ошибки, я ж говорю такие как на 2 картинке в самом первом посте((


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Orfus от Февраль 07, 2012, 11:35
Те 4 метода с QDataStream перенеси в файл где у тебя запись\чтение из сокета идут.

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


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 07, 2012, 12:46
Те 4 метода с QDataStream перенеси в файл где у тебя запись\чтение из сокета идут.

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

Огромное спасибо! Всё заработало как надо))


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: KrupaKarlo от Февраль 07, 2012, 13:54

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

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



Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 07, 2012, 14:34

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

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



НЕЛЬЗЯ в датастрим  запихнуть QVariant потому что для QVariant не определены операторы << и >> !


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Orfus от Февраль 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;
а вначале ценной части сообщения писал кол-во структур приходящих.


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 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. Где и как учился прогать ?)))


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Orfus от Февраль 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 уже полгода ковыряю и шишечек понабил уже себе. Учился большей частью сам по книжкам и примерам. Сейчас как раз место работы меняю чтоб на новом подучится у старших программировать правильно, а не индусокодить.


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 07, 2012, 17:34
Цитировать

Я не то чтобы опытный, просто сеть на Qt уже полгода ковыряю и шишечек понабил уже себе. Учился большей частью сам по книжкам и примерам. Сейчас как раз место работы меняю чтоб на новом подучится у старших программировать правильно, а не индусокодить.


Кстати о шишках а вот одна из них!((( Теперь на другую проблему наткнулся когда игроков (5-6) и более клиентов, при отсылке данных сервер падает иногда, но не всегда хмм... видимо слишком много данных что ли, хотя шлю всего структуру
Код:
struct PlayerInfo
{
    int players;
    int myPlayerNum;
};

всем игрокам, это типо когда игру стартую отсылаю всем чтобы каждый знал какой он по счёту игрок и сколько игроков в игре ваще.

Когда сервер падает вылезает  Runtime error


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Orfus от Февраль 07, 2012, 17:44
собирай отладочную версию и запускай в режиме отладки.


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 07, 2012, 18:18
собирай отладочную версию и запускай в режиме отладки.

вообщем вот такая ошибка:

 (http://imglink.ru/thumbnails/07-02-12/0e81ea73f1cf67c58d0a371edb0ab83d.jpg) (http://imglink.ru/show-image.php?id=db9e785dda6c10f21e79c4d418b59aac)

Сталкивался с такой?


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: Orfus от Февраль 07, 2012, 19:21
собирай отладочную версию и запускай в режиме отладки.

вообщем вот такая ошибка:

 (http://imglink.ru/thumbnails/07-02-12/0e81ea73f1cf67c58d0a371edb0ab83d.jpg) (http://imglink.ru/show-image.php?id=db9e785dda6c10f21e79c4d418b59aac)

Сталкивался с такой?

Ответ тот же.
собирай отладочную версию и запускай в режиме отладки.
Компилишь версию под названием отладка и запускаешь через кнопку F5 (по умолчанию в Qt Creator). 99% что ты что то напутал или не учел с размерами векторов.


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 07, 2012, 19:49

[/quote]
Компилишь версию под названием отладка и запускаешь через кнопку F5 (по умолчанию в Qt Creator). 99% что ты что то напутал или не учел с размерами векторов.
[/quote]

Хах... ты угадал. Исправил это. Дело в индексах было. Ну теперь логика игры страдает данные всё норм передаются но танки не правильно двигаются... Дальше дело за мной... Если какие опять непонятности будут напишу))


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: KrupaKarlo от Февраль 08, 2012, 07:55


Цитировать
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. Где и как учился прогать ?)))

я когда тебе писал про Q_DECLARE_METATYPE думал ты в ассистант зайдешь. Там прямо черным по былому ссылка на qRegisterMetaType а прямо после qRegisterMetaType идет описание void qRegisterMetaTypeStreamOperators ( const char * typeName )


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: LisandreL от Февраль 08, 2012, 08:16
Нельзя сериализацию QVariant с нестандартным типом через QDataStream для передачи по сети использовать.
Цитата: Serializing Qt Data Types
QVariant   
The type of the data (quint32)
The null flag (qint8)
The data of the specified type
Ибо у вас нет никакой гарантии, что на обеих сторонах типу выдастся одинаковый id.
То есть может это и сработает, пока у вас 1 модуль с qRegisterMetaType, но полагаться на это нельзя.


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 08, 2012, 10:06


я когда тебе писал про Q_DECLARE_METATYPE думал ты в ассистант зайдешь. Там прямо черным по былому ссылка на qRegisterMetaType а прямо после qRegisterMetaType идет описание void qRegisterMetaTypeStreamOperators ( const char * typeName )

Ни разу не пользовался ассистантом...


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: _OLEGator_ от Февраль 08, 2012, 10:21
Ни разу не пользовался ассистантом...

это фейл


Название: Re: QVector в QDataStream для передачи по сети! Помогите
Отправлено: lolbla2 от Февраль 08, 2012, 11:57
Ни разу не пользовался ассистантом...

это фейл

ага, справку юзаю f1 или в иннете