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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Сериализация данных для передачи по сети  (Прочитано 10998 раз)
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« : Март 31, 2015, 08:42 »

Клиент на Qt, сервер С++ (bost).

Есть структуры описывающие предметную область, как лучше их передавать по сети?
Структуры без указателей, типы: вектора(в том числе и на структуры), строки, простые типы.
« Последнее редактирование: Март 31, 2015, 12:48 от deMax » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Март 31, 2015, 08:43 »

Да как хочешь, хоть в xml перегоняй. Улыбающийся
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #2 : Март 31, 2015, 08:54 »

Json тоже неплох Улыбающийся
Записан

Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Март 31, 2015, 08:58 »

Если простые структуры, то проще использовать операторы << и >>. И создать теги, по-взрослому
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #4 : Март 31, 2015, 09:05 »

Json тоже неплох Улыбающийся
Объем передаваемых данных приличный, чтобы текстовый формат и парсинг использовать.

Да как хочешь, хоть в xml перегоняй. Улыбающийся
Для каждой структуры придется писать функцию сериализации и десериализации, можно ли это сделать автоматически?

Например как автоматически запаковать/распаковать это:
Код:
struct Data {
  std::string text;
  std::vector<Data> tree;}
« Последнее редактирование: Март 31, 2015, 09:08 от deMax » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #5 : Март 31, 2015, 09:42 »

msgpack
google protobuf
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #6 : Март 31, 2015, 10:45 »

Может, попробовать преобразовать класс в QVariant, а потом через QDataStream - в QByteArray, который передавать проще простого. Примерно так:
Код:
class MyClass{
public:
    int i;
    double d;
    QString str;
    MyClass();
};

Q_DECLARE_METATYPE(MyClass);

    MyClass s;
    QVariant var;
    var.setValue(s); // copy s into the variant

    QByteArray arr;
    QDataStream out(&arr,QIODevice::WriteOnly);
    out << *((QVariant*)var);   
   
    int dataLen = arr.size();
    char* data = arr.data();

    // передаем dataLen байт
    ...

    // принимаем и делаем обратное преобразование
    QByteArray arr = QByteArray::fromRawData(ptr,dataLen);
    QDataStream in(&arr,QIODevice::ReadOnly);
    QVariant val(in);

    // retrieve the value
    MyClass s2 = val.value<MyClass>();

Но как в структуре использовать стандартные вектора - без понятия.
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Март 31, 2015, 11:12 »

Для каждой структуры придется писать функцию сериализации и десериализации, можно ли это сделать автоматически?
Избегать этого не следует. И лучше не ф-цию а операторы << и >>, они уже сделаны для Qt типов

Например как автоматически запаковать/распаковать это:
Код:
struct Data {
  std::string text;
  std::vector<Data> tree;}
Напр так
Код
C++ (Qt)
template <class stream>
stream & operator << ( stream & strm, const Data & data )
{
strm << data.text << data.tree;
}
 
template <class stream>
stream & operator >> ( stream & strm, Data & data )
{
strm >> data.text >> data.tree;
}
Да, придется писать операторы для std::string и std::vector, напр
Код
C++ (Qt)
template <class stream, class vec>
stream & operator << ( stream & strm, const vec & data )
{
strm << data.size();
for (size_t i = 0; i < data.size(); ++i)
 strm << data[i];
}
Но это надежно, капитально. А пытаясь словчить, сэкономить Вы потом потеряете куда больше времени латая дыры
« Последнее редактирование: Март 31, 2015, 11:14 от Igors » Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #8 : Март 31, 2015, 12:48 »

Old, Igors спасибо.

protobuf неплохая штука, не знал. Возможно позже добавлю.

Через потоки в принципе неплохое решение получается. Я примеры похожие видел, только с вектором не додумался.

p.s. в идеале хотелось бы макрос который сам сгенерирует эти функции.
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #9 : Апрель 01, 2015, 09:07 »

strm >> data.text >> data.tree;
Если использовать std::stringstream (вместо QDataStream) то все данные уходят в строку, есть ли аналоги потоков на с++ или строку по символу считывать?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #10 : Апрель 01, 2015, 09:38 »

strm >> data.text >> data.tree;
Если использовать std::stringstream (вместо QDataStream) то все данные уходят в строку, есть ли аналоги потоков на с++ или строку по символу считывать?
А вам msgpack не понравился?
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #11 : Апрель 01, 2015, 09:52 »

На хабре статью смотрел. Смутило следующее:
Цитировать
И скормил его всем упаковщикам. Пикл в этом списке лишь из-за того что сервер на пайтоне.

На выходе я получил такие цифры упаковки
Size test
19266 cbor
19284 msgpack
41726 json
25363 pickle

Ну, круто. Действительно качественная упаковка, жаль только под CBOR в пайтон версии нету stringref, былоб еще мельче.
А что со скоростью упаковки и распаковки?

Этот самый объект скушал 100 раз в цикле каждому упаковщику.
4.65940260887146 cbor
4.218739032745361 msgpack
0.2644484043121338 json
0.057727813720703125 pickle

4.5 секунды, как-то много всего для 100 разовой упаковки.
msgpack идет вместе с С++ кодом, а не упаковывается чисто на пайтоне, но все равно 4.2 секунды — слишком много
json показал нормальный результат, а вот пикл невероятно порадовал.

Упаковка пол беды, что с распаковкой?

4.128425598144531 cbor
7.117578029632568 msgpack
0.19976019859313965 json
0.08250904083251953 pickle

Хммм, CBOR показал такие-же как и при упаковке, а вот message pack подкачала.
JSON в пределах нормы, пикл снова радует.

У меня приложение клиент сервер, все данные на сервере, их не мало и они постоянно обновляются(сервер с удаленными БД работает).

Но для развития посмотрю.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #12 : Апрель 01, 2015, 09:54 »

Попробуйте сами протестировать, а не принимать решения по статьям с хабра. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Апрель 01, 2015, 10:32 »

Если использовать std::stringstream (вместо QDataStream) то все данные уходят в строку, есть ли аналоги потоков на с++ или строку по символу считывать?
Если Вы планируете сохранять данные в читабельном виде (stringstream, QTextStream), то Вы и отвечаете за их формат (разделители, концы строк и.т.п). Делайте свой поток на базе stringstream, где напр строки будут браться в кавычки. Непонятно зачем нужен текст для передачи по сети.
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #14 : Апрель 01, 2015, 10:42 »

На хабре статью смотрел. Смутило следующее:
Цитировать
И скормил его всем упаковщикам. Пикл в этом списке лишь из-за того что сервер на пайтоне.

На выходе я получил такие цифры упаковки
Size test
19266 cbor
19284 msgpack
41726 json
25363 pickle

Ну, круто. Действительно качественная упаковка, жаль только под CBOR в пайтон версии нету stringref, былоб еще мельче.
А что со скоростью упаковки и распаковки?

Этот самый объект скушал 100 раз в цикле каждому упаковщику.
4.65940260887146 cbor
4.218739032745361 msgpack
0.2644484043121338 json
0.057727813720703125 pickle

4.5 секунды, как-то много всего для 100 разовой упаковки.
msgpack идет вместе с С++ кодом, а не упаковывается чисто на пайтоне, но все равно 4.2 секунды — слишком много
json показал нормальный результат, а вот пикл невероятно порадовал.

Упаковка пол беды, что с распаковкой?

4.128425598144531 cbor
7.117578029632568 msgpack
0.19976019859313965 json
0.08250904083251953 pickle

Хммм, CBOR показал такие-же как и при упаковке, а вот message pack подкачала.
JSON в пределах нормы, пикл снова радует.

У меня приложение клиент сервер, все данные на сервере, их не мало и они постоянно обновляются(сервер с удаленными БД работает).

Но для развития посмотрю.

Там также говорилось, что связка json+zip очень хорошая Улыбающийся
Записан

Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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