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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Как записать структуру в QByteArray  (Прочитано 18387 раз)
Magnolia
Гость
« : Апрель 18, 2012, 14:20 »

Всем привет! Впервые работаю с UDP сокетами, поэтому возникли проблемы. Пытаюсь записать в сокет структуру, для этого использую прототип функции qint64 QIODevice::write ( const QByteArray & byteArray ). Вот код:
Код:
 QByteArray buff;
            memmove(&buff, &tt, sizeof(tt));
            udp->write(buff);
(tt - это как раз структура (struct), udp - udpсокет).
В результате в масиив buff ничего не записывается. Подскажите как и что делать Улыбающийся
Записан
mutineer
Гость
« Ответ #1 : Апрель 18, 2012, 14:26 »

да ты крутой, однако, так делать...
Тебе надо сериализовать свою структуру в QByteArray
« Последнее редактирование: Апрель 18, 2012, 14:30 от mutineer » Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #2 : Апрель 18, 2012, 14:33 »

Всем привет! Впервые работаю с UDP сокетами, поэтому возникли проблемы. Пытаюсь записать в сокет структуру, для этого использую прототип функции qint64 QIODevice::write ( const QByteArray & byteArray ). Вот код:
Код:
 QByteArray buff;
            memmove(&buff, &tt, sizeof(tt));
            udp->write(buff);
(tt - это как раз структура (struct), udp - udpсокет).
В результате в масиив buff ничего не записывается. Подскажите как и что делать Улыбающийся


Можно с осторожностью передавать только упакованные стуктуры по сети и при отстутствии в них не-pod полей.
Важно учесть, что на архитектурах процессоров с обратным порядком байт в целых числах (PowerPC например) твою структуру не поймут.

Вот так правильней:
Код:
udp->write(&tt, sizeof(tt));

Для объявление упакованной структуры в разных компиляторах используются разные директивы. Так что гугли.
« Последнее редактирование: Апрель 18, 2012, 14:35 от navrocky » Записан

Гугль в помощь
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


Просмотр профиля WWW
« Ответ #3 : Апрель 18, 2012, 14:41 »

memmove(&buff, &tt, sizeof(tt));
You make my day.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Magnolia
Гость
« Ответ #4 : Апрель 18, 2012, 14:54 »

да ты крутой, однако, так делать...
Тебе надо сериализовать свою структуру в QByteArray
Можно поподробнее? И кстати, я девушка
Записан
Странник
Гость
« Ответ #5 : Апрель 18, 2012, 17:06 »

если на другом конце тоже Qt-приложение болтается, проще использовать QDataStream.
Записан
Magnolia
Гость
« Ответ #6 : Апрель 19, 2012, 15:32 »

На другом конце железка болтается.
Проблему решила
Код:
 
    QByteArray buff;
    buff.clear();
    buff.resize(56);
    unsigned char buffer[56] = {0};
    memmove(&buffer,(unsigned char *)&tt, 56);
    for(int i = 0; i <56; i++)
        buff[i] = buffer[i];
    udp->writeDatagram(buff.data(),56,QHostAddress("192.168.0.81"),9800);
Не знаю уж насколько это правильно но ... Работает, пыхтит Улыбающийся
ЗЫ
Пакет всегда размером 56 байт
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Апрель 19, 2012, 15:45 »

Не знаю уж насколько это правильно но ...
Ну вообще-то не очень  Улыбающийся Лучше так
Код
C++ (Qt)
QByteArray buff;
buff.resize(sizeof(tt));
memmove(buff.data(), &tt, sizeof(tt));
 
А структура должна быть объявлена (на обеих сторонах) примерно так
Код
C++ (Qt)
#pragma pack(push, 4)
struct MyTT {
int  member1;
...
};
#pragma pack(pop)
 
Структура не может быть классом с виртуальными методами и не должна иметь никаких членов-указателей, т.к. адреса теряются при передаче

Даже при всем этом нельзя назвать такой подход "правильным". По-взрослому надо сериализоваться в QDataStream
Записан
bez_glaz
Гость
« Ответ #8 : Апрель 19, 2012, 15:54 »

Аналогичная ситуация передачи у меня по UDP структуры.
Воспользовался
Код:
QByteArray buff;
buff.resize(sizeof(tt));
memmove(buff.data(), &tt, sizeof(tt));
Всё на ура.
А можно по подробнее с QDataStream?
Хотелось бы грамотно кодить приложение, а не чтоб работало.
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #9 : Апрель 19, 2012, 19:44 »

Можно с осторожностью передавать только упакованные стуктуры по сети и при отстутствии в них не-pod полей.
Важно учесть, что на архитектурах процессоров с обратным порядком байт в целых числах (PowerPC например) твою структуру не поймут.
Ещё не все типы имеют гарантированно одинаковый размер на разных архитектурах.

А можно по подробнее с QDataStream?
Хотелось бы грамотно кодить приложение, а не чтоб работало.
Перегружаете опретароы << и >> для вашего типа. Внутри сериализуете/десериализуете по полям в одном порядке, приводя их к типам указанным в Serializing Qt Data Types (не long, а qint64 и т.п.).
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #10 : Апрель 20, 2012, 23:39 »

Аналогичная ситуация передачи у меня по UDP структуры.
Воспользовался
Код:
QByteArray buff;
buff.resize(sizeof(tt));
memmove(buff.data(), &tt, sizeof(tt));

В чем сакральный смысл копирования структуры сперва в QByteArray, а затем отсылки этого же в сокет? Зачем эти не нужные промежуточные шаги?
Записан

Гугль в помощь
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Апрель 21, 2012, 11:32 »

В чем сакральный смысл копирования структуры сперва в QByteArray, а затем отсылки этого же в сокет? Зачем эти не нужные промежуточные шаги?
Возможно нужна длина пакета
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #12 : Апрель 21, 2012, 13:04 »

В чем сакральный смысл копирования структуры сперва в QByteArray, а затем отсылки этого же в сокет? Зачем эти не нужные промежуточные шаги?
Возможно нужна длина пакета

Какая длина пакета? Каким образом QByteArray может помочь с длиной пакета?
Записан

Гугль в помощь
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Апрель 21, 2012, 13:28 »

Какая длина пакета? Каким образом QByteArray может помочь с длиной пакета?
Записали структуру в QByteArray. Отослали сначала QByteArray.size(), потом сами данные. Так часто приходится делать (и не только с сокетами), т.к. на приемник должен знать сколько читать.
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #14 : Апрель 21, 2012, 21:39 »

В приведенном выше коде я этого не видел. Да и size можно передавать без QByteArray.
Записан

Гугль в помощь
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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