Russian Qt Forum

Qt => Вопросы новичков => Тема начата: unduty от Декабрь 27, 2020, 11:29



Название: quint16 uint16_t
Отправлено: unduty от Декабрь 27, 2020, 11:29
Клиент на микроконтроллере (STM32) имеет такой тип , размер 12 байт
struct uidType{
    uint16_t uid1 = 0;
    uint16_t uid2 = 0;
    uint32_t uid3 = 0;
    uint32_t uid4 = 0;
};

На сервере QT тип : (windows , linux)

struct uidType2{
    quint16 uid1 = 0;
    quint16 uid2 = 0;
    quint32 uid3 = 0;
    quint32 uid4 = 0;
};

можно ли его просто заполнять пакетом 12 байт? В чем различие типов?


Название: Re: quint16 uint16_t
Отправлено: kambala от Декабрь 27, 2020, 11:36
различий нет, просто некоторые платформы могут не знать о uintX_t. Можешь посмотреть определение quintX в заголовочном файле.


Название: Re: quint16 uint16_t
Отправлено: Igors от Декабрь 27, 2020, 11:48
можно ли его просто заполнять пакетом 12 байт? В чем различие типов?
Наверно Вы хотели спросить типа "будет ли корректно работать memmove или memcpy для быстрого присваивания". Да, здесь будет. Но лучше все-таки нарисовать тупые операторы присваивания почленно. Потому что напр так
 
Код:
struct uidType{
    uint16_t uid1 = 0;
    uint32_t uid2 = 0;
    uint16_t uid3 = 0;
    uint32_t uid4 = 0;
};
И уже хз (зависит от выравнивания). И если Вы собрались резво читать блоком из потока - тоже не стоит.


Название: Re: quint16 uint16_t
Отправлено: Old от Декабрь 27, 2020, 14:21
А с какой стати memmove и memcpy перестанут работать? Как выравниевание данных ломает работу этих функций?
А sizeof будет работать? Он правильно размер структуры с учетом выравнивания вычисляет?


Название: Re: quint16 uint16_t
Отправлено: unduty от Декабрь 28, 2020, 09:47
Наверно Вы хотели спросить типа "будет ли корректно работать memmove или memcpy для быстрого присваивания".
Мне нужно передавать по сети огромное количество пакетов по 48 байт, конструкция QDataStream мне кажется избыточной.
Хочется просто заливать структуру в QByteArray и отправлять в сокет, тоже при приеме в обратном порядке.
Другого способа быстрого наполнения массивов структур не нашел.


Название: Re: quint16 uint16_t
Отправлено: unduty от Декабрь 28, 2020, 09:52
различий нет, просто некоторые платформы могут не знать о uintX_t.

Другая сторона 32 битный микроконтроллер ARM, код на С. Qt типов там нет, мне нужно понимать могу ли я использовать однотипные массивы с обоих сторон?  а данные передавать блоком из байт который равен размеру структуры.


Название: Re: quint16 uint16_t
Отправлено: tux от Декабрь 28, 2020, 09:56
Байты - это просто байты. По 8 бит каждый. :)
Можете, конечно.
А "знает - не знает"... в конце концов можно придумать свой тип данных и использовать его с обоих сторон. Если так хочется заморачиваться. :)


Название: Re: quint16 uint16_t
Отправлено: Old от Декабрь 28, 2020, 09:57
Мне нужно передавать по сети огромное количество пакетов по 48 байт, конструкция QDataStream мне кажется избыточной.
Хочется просто заливать структуру в QByteArray и отправлять в сокет, тоже при приеме в обратном порядке.
Другого способа быстрого наполнения массивов структур не нашел.
Лучше использовать QDataStream и более того переводить все данные с учетом сетевого порядка байт (big endian). Кстати в QDataStream он используется по умолчанию.
Это хорошая практика. Формирование пакетов через QDataStream не добавляет каких-то значимых издержек.


Название: Re: quint16 uint16_t
Отправлено: kuzulis от Декабрь 28, 2020, 11:47
и я бы еще завернул структуры в pragma pack и их аналоги. чтобы точно знать что будет передано то что надо.

и датастрим тут избыточен, имхо.


Название: Re: quint16 uint16_t
Отправлено: Igors от Декабрь 28, 2020, 13:17
Мне нужно передавать по сети огромное количество пакетов по 48 байт, конструкция QDataStream мне кажется избыточной.
Хочется просто заливать структуру в QByteArray и отправлять в сокет, тоже при приеме в обратном порядке.
Другого способа быстрого наполнения массивов структур не нашел.
"Заливать/выливать" с помощью memmove/memcpy будет работать для конкретной структуры выше, но в общем случае этот способ ненадежен. А вот QDataStream (почленно) будет работать железно для любых структур. Нарисовать неск операторов << и >> переживете, не стоит на этом экономить. "Подальше положишь - поближе возьмешь"

И еще неплохо бы записать идентификатор, размер и версию структуры, чтобы потом не бегать


Название: Re: quint16 uint16_t
Отправлено: unduty от Декабрь 28, 2020, 13:46
Лучше использовать QDataStream и более того переводить все данные с учетом сетевого порядка байт (big endian). Кстати в QDataStream он используется по умолчанию.
Это хорошая практика. Формирование пакетов через QDataStream не добавляет каких-то значимых издержек.

   
Код:
QByteArray errorByteArr;
    QDataStream out(&errorByteArr, QIODevice::WriteOnly | QIODevice::Append);
    out.setByteOrder(QDataStream::BigEndian);
    out << (quint8) STM32_PACK_TITLE;
    out << (quint8) STM32_PACK_SIZE;
    out << (quint16) 0x0000;
    out << (quint8) 0xFF;
    out << (quint16) errorCode;
...................
socketClient.write(errorByteArr,STM32_PACK_SIZE);



Вы имеете в виду такую конструкцию ? будет ли она производительной?

Отдельно хотел спросить, как лучше построить очередь на отправку , если процедура отправки вызвана повторно до ее завершения (две параллельные отправки в одном сокете ) ?


Название: Re: quint16 uint16_t
Отправлено: unduty от Декабрь 28, 2020, 13:55
и я бы еще завернул структуры в pragma pack и их аналоги. чтобы точно знать что будет передано то что надо.

и датастрим тут избыточен, имхо.
В моем случае пакет всегда одной длинны, это связано с ограничением клиента на микроконтроллере, он джет всегда 48 байт, в котором есть заголовок, и контрольная сумма.
Как у начинающего Qtиста инструкция датастрим не вызывает доверия, проверить размер отправки можно только через отладку, непонятно насколько она будет задерживать отправку простых сообщений.


Название: Re: quint16 uint16_t
Отправлено: tux от Декабрь 28, 2020, 15:45
Зачем вам тут датастримы? Простой структуры с побайтным выравниванием хватит более чем :)


Название: Re: quint16 uint16_t
Отправлено: Old от Декабрь 28, 2020, 19:05
Код:
[quote author=unduty link=topic=32909.msg243757#msg243757 date=1609152403]
Вы имеете в виду такую конструкцию ? будет ли она производительной?

Да, никаких просадок производительности эта конструкция не вызывает.
Зато вы всегда будете знать в каком виде ваши данные уходят в сеть, не зависимо от архитектуры процессора.

Лучше просто:
Код
C++ (Qt)
   socketClient.write( errorByteArr );
 


Отдельно хотел спросить, как лучше построить очередь на отправку , если процедура отправки вызвана повторно до ее завершения (две параллельные отправки в одном сокете ) ?
В ядре есть своя очередь на отправку, в сокетах Qt есть еще одна очередь на отправку, думаю в сетевом стеке для микроконтроллерах тожее есть своя очередь.