Название: 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(); Если машины не в локальной сети, неплохо бы повторить OnReceiveData() в конце метода OnReceiveData(), ибо новые пакеты придут, а сигнала не будет. 3)Про стрим не подскажу, но объясните мне кто нибудь зачем делать отдельный метод? Что мешает делать Код: in>>data.b_dir; 4) Делать сеть внутри GUI потока черевато. 5) после прочтения данных, стоило бы сделать blockSize=0; Название: Re: QVector в QDataStream для передачи по сети! Помогите Отправлено: lolbla2 от Февраль 06, 2012, 13:14 1)пользуйтесь тегам кода 2)В слоте void Widget::OnReceiveData() вместо поисков нужного сокета можно использовать Код: QTcpSocket* TCPSocket = (QTcpSocket*)sender(); Если машины не в локальной сети, неплохо бы повторить OnReceiveData() в конце метода OnReceiveData(), ибо новые пакеты придут, а сигнала не будет. 3)Про стрим не подскажу, но объясните мне кто нибудь зачем делать отдельный метод? Что мешает делать Код: in>>data.b_dir; 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 Серверное приложение отдельно. Клиент когда сдвинул танчик или стрельнул, то серверу приходят от него данные и сервер в свою очередь всем игрокам рассылает данные о всех танчиках, но каждому не шлёт егошние данные, то есть игроку 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{ Код: QDataStream &operator>>(QDataStream &in, promp &inp){ Код: Запускается D:\qt\projects\LIC_NEW\release\CRYPTER.exe... Название: 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){ Код: Запускается D:\qt\projects\LIC_NEW\release\CRYPTER.exe... Методы записи чтения те же. Структурка та же. Название: Re: QVector в QDataStream для передачи по сети! Помогите Отправлено: KrupaKarlo от Февраль 06, 2012, 16:14 GUI будет провисать в моменты объемных приёмов\передач. Я не имею ни малейшего понятия насколько велик поток трафика в ваших приложениях, но если он объёмный стоит задуматься о классе для сети и отдельном потоке. Ну вообще делаю игру танчики на подобии дендевской. Максимум 6 игроков. Как Вы уже наверно догадались структура для передачи данных имеет вид: Код: struct Input Серверное приложение отдельно. Клиент когда сдвинул танчик или стрельнул, то серверу приходят от него данные и сервер в свою очередь всем игрокам рассылает данные о всех танчиках, но каждому не шлёт егошние данные, то есть игроку 1 шлёт данные о игроках 2,3,4,5,6. Игроку 2 данные о игроках 1,3,4,5,6 и т д. В Qt есть такая вещь как Q_DECLARE_METATYPE Код: struct 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) { Я взял егто из примера про fortune client/server Название: Re: QVector в QDataStream для передачи по сети! Помогите Отправлено: lolbla2 от Февраль 06, 2012, 19:42 Цитировать В Qt есть такая вещь как Q_DECLARE_METATYPE Код: struct MyStruct Это позволяет запихивать и доставать свои типы из QVariant ИМХО так будет попроще делать) чем структуры в сокет пихать Я пробовал рассмотреть такой вариант, но да можно запихнуть тогда свой класс в обёртку QVariant, но возникает проблема что QVariant не запихнуть в QDataStream ибо нужно определить операторы << и >> для QVariant Название: Re: QVector в QDataStream для передачи по сети! Помогите Отправлено: lolbla2 от Февраль 06, 2012, 19:50 challenge accepted :P Код: int main(int argc,char** argv){ Код: Запускается D:\qt\projects\LIC_NEW\release\CRYPTER.exe... Методы записи чтения те же. Структурка та же. Хмм забавно таки.... Создал те же самые проверки для своей структуры всё работает. А вот в приложении где сервер пишу почему-то ошибки вылезают как на 2 картинке в 1 сообщении в теме... Что это может быть?(( Название: Re: QVector в QDataStream для передачи по сети! Помогите Отправлено: lolbla2 от Февраль 06, 2012, 20:05 Оо выяснил, с файлами работает, с сокетами не пашет, ошибки вылезают (( вот попробуй сам))
Название: Re: QVector в QDataStream для передачи по сети! Помогите Отправлено: Orfus от Февраль 07, 2012, 10:47 Никакой зависимости файл или сокет нету. Ты определяешь как пихать в QDataStream, а уже с чем он связан дело десятое. Я не ванга, ошибки удалённо вылетающие не вижу.
client.срр Код: #include <QtCore> Код: #ifndef CLIENT_H server.h Код: #ifndef SERVER_H Код: #include <QApplication> вывод клиента Код: Запускается D:\qt\projects\LIC_NEW\release\CRYPTER.exe... Код: Запускается D:\qt\projects\serv\debug\serv.exe... Название: 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 не определены операторы << и >> ! Код: #include <QtCore> выкидывает Код: QVariant::save: unable to save type 258. Но мне всё это не нравится по одной причине. и QVector и QVariant жрут больше ресурсов, чем нужно для задачи. Я бы пихал ручками Код: out<<p1.val1<<p1.val2<<p1.val3; Название: Re: QVector в QDataStream для передачи по сети! Помогите Отправлено: lolbla2 от Февраль 07, 2012, 16:15 Цитировать o rly? Код: #include <QtCore> выкидывает Код: QVariant::save: unable to save type 258. Но мне всё это не нравится по одной причине. и QVector и QVariant жрут больше ресурсов, чем нужно для задачи. Я бы пихал ручками Код: out<<p1.val1<<p1.val2<<p1.val3; Я же говорил надо определить операторы << и >>, но я же не знал что их можно определить так просто с помощью qRegisterMetaTypeStreamOperators<MyClass>("MyClass"); Кстати а для чего нужно Код: qRegisterMetaType<promp>("promp"); Разве макрос Код: Q_DECLARE_METATYPE(promp) Возможно много ресурсов жрёт но писать out<<p1.val1<<p1.val2<<p1.val3; а у меня так как ты видел 11 полей в структуре слишком не читабельный код делает. Наверно, конечно, я неправильно подхожу к данной задаче, но мне пока бы сделать так чтобы работало вообще и не важно сколько ресурсов жрёт, об оптимальности подумаю позже. Особенно мне понравилась идея сделать передачу и приём данных в отдельном потоке. Может сделаю позже, а пока хочу чтобы вообще это хотя бы так работало. P.S. Orfus я вижу ты опытный программист, респект xD. Где и как учился прогать ?))) Название: Re: QVector в QDataStream для передачи по сети! Помогите Отправлено: Orfus от Февраль 07, 2012, 16:50 ... Их в любом случае, будешь ты использовать QVariant или QVector необходимо описывать.Я же говорил надо определить операторы << и >>, но я же не знал что их можно определить так просто с помощью qRegisterMetaTypeStreamOperators<MyClass>("MyClass"); Кстати а для чего нужно Первый регистрирует, второй декларирует. В доках должно быть описано что делает каждый из них, но нужны оба. Я с ними сталкивался только когда свои типы в сигнал\слоты добавлял.Код: qRegisterMetaType<promp>("promp"); Разве макрос Код: Q_DECLARE_METATYPE(promp) Возможно много ресурсов жрёт но писать 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 всем игрокам, это типо когда игру стартую отсылаю всем чтобы каждый знал какой он по счёту игрок и сколько игроков в игре ваще. Когда сервер падает вылезает 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> выкидывает Код: QVariant::save: unable to save type 258. Но мне всё это не нравится по одной причине. и QVector и QVariant жрут больше ресурсов, чем нужно для задачи. Я бы пихал ручками Код: out<<p1.val1<<p1.val2<<p1.val3; Я же говорил надо определить операторы << и >>, но я же не знал что их можно определить так просто с помощью qRegisterMetaTypeStreamOperators<MyClass>("MyClass"); Кстати а для чего нужно Код: qRegisterMetaType<promp>("promp"); Разве макрос Код: Q_DECLARE_METATYPE(promp) Возможно много ресурсов жрёт но писать 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 Ибо у вас нет никакой гарантии, что на обеих сторонах типу выдастся одинаковый id.The type of the data (quint32) The null flag (qint8) The data of the specified type То есть может это и сработает, пока у вас 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 или в иннете |