Russian Qt Forum

Qt => Работа с сетью => Тема начата: darkfog от Июнь 19, 2018, 15:20



Название: Сквозная передача данных через сервер.
Отправлено: darkfog от Июнь 19, 2018, 15:20
Проблема такая. Два клиента подключаются к серверу. Первый клиент оправляет класс серверу с пометкой что нежно передать эти данные второму клиенту. И вот вопрос как передать второму клиенту отправленный класс без десериализации класса на стороне сервера, но с проверкой целостности пакета. Затык в том как из одного QDataStream перекинуть данные в другой. Вроде понятно что данные внутри находятся в типе QByteArray, но если извлечь их в переменную QByteArray и отправить клиенту 2 то там данные не десириализуются получается пустая переменная.


Название: Re: Сквозная передача данных через сервер.
Отправлено: RedDog от Июнь 19, 2018, 16:47
Пакет должен содержать размер данных.
См. пример Fortune Server/Client


Название: Re: Сквозная передача данных через сервер.
Отправлено: darkfog от Июнь 20, 2018, 08:46
Проверку на размер я сделал. Фишка в том что мне приходится все равно извлекать данные из пришедшего потока. Как оставшиеся данные переправить дальше без их извлечения или извлечь в таком формате чтобы не пришлось десериализовывать. Я пробовал извлекать данные в QByteArray, но тогда при передаче дальше 2 клиенту данные не десириализуются. В классе 3 переменные QMap QHash и QVector и если извлекать в QByteArray то они все кладутся в одну перемененную. Вот так происходит сериализация класса QDataStream & operator<<(QDataStream &d, testClass &u)
{
    d << u.getVect() << u.getList() << u.getHash();
    return d;
}

А так десеарилизация
QDataStream & operator>>(QDataStream &d, testClass &u)
{
    d >> u.vector >> u.list >> u.hash;
    return d;
}


Название: Re: Сквозная передача данных через сервер.
Отправлено: Пантер от Июнь 20, 2018, 09:34
> с проверкой целостности пакета

TCP гарантирует целостность, что тебе еще нужно? Качай из одного, пихай в другой.


Название: Re: Сквозная передача данных через сервер.
Отправлено: darkfog от Июнь 20, 2018, 10:11
Чтобы извлечь его полюбас необходимо десериализовать, а я хочу дернуть размер пакета проверить совпадает ли, а то что остальное лежит в QDataStream напрямки без засовывания в переменные переслать дальше. Или извлечь в универсальном виде и отправить. Просто будут разные классы отправятся (этот тестовый) и будет больше чем 2 клиента. Вот и вопрос как данные извлечь в общем виде чтобы не приходилось делать десериализацию 2 раза на стороне Сервера и получающего клиента поскольку тогда сервак окажется перегруженным. Пробовал кидать остаток того что лежит в QDataStream в QByteArray добавлять снова спереди размер и отправлять 2ому клиенту, но тогда не проходит десериализация у клиента  да и по моему  что-то не то записывается в QByteArray.


Название: Re: Сквозная передача данных через сервер.
Отправлено: RedDog от Июнь 20, 2018, 11:03
В общем случае, проблем быть не должно, если пакеты полностью пересылаются, хоть через десяток соаетов их пропусти.
Видимо проблема кроется в "битости" пакета, либо не соответствии методов сериализации.
Для лучшего понимания проблемы, логируйте в хексе принимаемые и отправляемые данные и на клиентах и на сервере.


Название: Re: Сквозная передача данных через сервер.
Отправлено: darkfog от Июнь 20, 2018, 11:31
Я так и не решил проблему пересылки в общем виде. По этому решил вместо держания на сервере всех пересылаемых классов. Создать структуры с нужными типами данных, а в пакете после размера посылать указатель какую структуры для десериализации использовать. Громоздкость несколько уменьшилась, но проблема в основе осталась.


Название: Re: Сквозная передача данных через сервер.
Отправлено: vic57 от Июнь 27, 2018, 03:39
Я так и не решил проблему пересылки в общем виде. По этому решил вместо держания на сервере всех пересылаемых классов. Создать структуры с нужными типами данных, а в пакете после размера посылать указатель какую структуры для десериализации использовать. Громоздкость несколько уменьшилась, но проблема в основе осталась.
по сети вы передаете байты и транспорту не важно, что внутри пакета.
я бы сделал по типу Ethernet - преамбула + контр. сумма
http://samoychiteli.ru/document33155.html
или преамбула начала (16 байт к примеру) и маркер конца пакета(16 байт )
читаете первые и последние байты из ByteArray и все
для сериализации в инете обычно json
есть и для qt
https://habr.com/post/147952/


Название: Re: Сквозная передача данных через сервер.
Отправлено: vic57 от Июнь 27, 2018, 20:24
вот простой пример
Код
C++ (Qt)
   QByteArray ba;
   QDataStream s(&ba,QIODevice::ReadWrite);
   ba += "\n\n\n\n\n\n\n\r";
   QVector<double> v;
   v.fill(-10,10);
   s.device()->seek(8);
   s << v;//serialization
   v.clear();
   ba += "\n\n\n\n\n\n\n\r";
   QByteArray b,a;
   a = ba.left(8);
   b = ba.right(8);
   qDebug() << a << b;
   s.device()->seek(8);
   s >> v;//deserialization
   qDebug() << v << v.size();