Как принимать и разбирать по UDP QByteArray в структуру из битовых полей?

Есть 2 структуры битовых полей объединенные в одну структуру. Раньше когда общий размер структуры позволял, делал объединение через union в uint64. Сейчас размер структур стал больше, передаю в QByteArray с сервера клиенту и теперь появилась проблема с приемом и разбором.

Как правильно это делают нормальные люди? можно еще с пример, буду рад!
  • Вопрос задан
  • 1131 просмотр
Решения вопроса 1
@kukiman Автор вопроса
Решил , но не без помощи сообщества, Спасибо.

Код структуры:

#pragma pack(push, 1) // работает без директив
struct srt_t // размер структуры 160 бит или 20 байт
{
    uint8_t one;
    uint8_t two;
    uint16_t three;
    uint32_t four;
    uint64_t five;
    uint32_t six;
};
#pragma pack(pop)

Код кодирования структуры в QByteArray:

srt_t ht{ 255, 255, 65535, 4294967295, 9223372036854775807, 255 };

    QByteArray arr;
    arr.append( reinterpret_cast<char *>( &ht ), sizeof( ht ) );

Код декодирования в структуру:

srt_t *pDev1 = reinterpret_cast<srt_t *>( arr.data() );

    qDebug() << pDev1->one;
    qDebug() << pDev1->two;
    qDebug() << pDev1->three;
    qDebug() << pDev1->four;
    qDebug() << pDev1->five;
    qDebug() << pDev1->six;
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
gbg
@gbg
Любые ответы на любые вопросы
Если гипотетически, ваша программа будет переноситься между разными компиляторами, процессорами, и архитектурами, вам придется учесть множество нюансов:

1) простое копирование данных из пакета в структуру будет работать только в том случае, если на обеих машинах одинаковая архитектура процессора и один и тот же компилятор. В противном случае возможны нюансы с выравниванием полей в структуре (его надо отключить) и с порядком хранения байт (а тут уже начинаются проблемы)

2) разные архитектуры процессоров хранят целые числа с разным порядком байт. Чтобы не возникало конфликтов, принято по сети передавать данные в сетевом порядке байт. Для перевода в него есть семейства функций hton[s|l]/ntoh[s|l] . Без них вы будете наблюдать жуткие глюки.

Отсюда следует, что нельзя просто так (тм) копирнуть байты, пришедшие из сети куда-то там, нужно как минимум преобразовать их из сетевого порядка в хостовый (а при отсылке - из хостового в сетевой), и уже потом заталкивать в поля структуры (так что выравнивание можно и не отключать в таком случае).
Ответ написан
Комментировать
IGHOR
@IGHOR Куратор тега Qt
Qt/C++ DEV/CTO
Через
reinterpret_cast<char*>(указатель на объект вашей структуры)
получите указатель на массив в который можно записать данные из QByteArray.
А саму структуру обернуть в код:
#pragma pack(push, 1)
структура
#pragma pack(pop)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы