Я разрабатываю приложение C для связи с одним из реальных устройств системы управления. Устройство использует четко определенную структуру протокола. Например, рассмотрим один из структуры, устройство посылает как пакет UDP при запросе: -Предложения по декодированию UDP-пакетов
typedef struct poll_request_s {
uint16 poll_number; /* poll number mirrored from the
* poll request */
uint16 length; /* length of the message */
/* till above it was all header section this is ACTUAL DATA */
attribute_list_t attr_list; /* this attribute list contains
* various attributes */
} poll_request_t
Теперь attribute_list_t
является структурой, которая упаковывает различные атрибуты и каждый атрибут в этом списке идентифицируется номером идентификатор, который uint16
(16-битное целое число). Таким образом, в коротком протоколе работает примерно так: -
- Вы запрашиваете данные.
- Вы получаете данные в виде списка атрибутов.
- Каждый атрибут в списке атрибутов имеет идентификатор объекта.
- Вы анализируете каждый атрибут (преобразовываете в порядок байтов хоста), используя этот идентификатор объекта.
- Атрибут может содержать больше списка атрибутов. (Атрибутов создания)
Это atrtribute_list_t
структура является то, как показано ниже: -
typdef struct attribute_list_s {
uint16 length; /* length of attribute list */
uint16 count; /* number of attributes in this list */
uint8 attrs_data[]; /* another container to hold attributes' data */
} attribute_list_t
Теперь attrs_data
только место держатель для хранения всех атрибутов в списке. Фактически этот attrs_data
должен быть отлит в другую структуру, называемую ava_type
, чтобы прочитать информацию об атрибутах.
typdef struct ava_type_s {
uint16 attr_id; /* type of attribute */
uint16 length; /* length of this attribute
*(this length of single attribute not whole list*/
uint8 data[]; /* another flexible array to hold data for this
* attribute type */
}
Теперь для того, чтобы итерацию и разобрать атрибуты внутри этой структуры, я в настоящее время с помощью этого алгоритма (псевдо-код ниже):
uint8* packet = recv_packet(SOCKET);
/* this is used as packet iterator pointer */
unit8* packet_ptr = packet;
parsed_packet_t parsed_packet = malloc(SOME_SIZE);
.
. /* do header un-packing */
.
/* dont need attribute_list length so skip this 2 bytes */
parsed_packet += 2;
/* parsed packet do nee count of attributes */
parsed_packet.attribute_list->count = NTOHS(packet_ptr);
packed_ptr += 2; /* skip count */
/* now packet_ptr is pointer to attr_list */
offset = 0, i = 0;
for(i = 0 to attr_list->count) {
/* cast the attributes' data to ava_type */
packet_ptr += offset;
/* parse object identifier */
parsed_packet.attribute_list->data[i++].object_id = NTOHS(packet_ptr);
packet_ptr += 2; /* skip 2 bytes */
/* next offset would be attribute length of this packet */
attribute_length += 2 + NTOHS(packet_ptr);
packet_ptr += 2;
/* now we are pointer to actual data of i(th) attribute */
/* I've made this parser structure and hash table to
* retrieve the parser for particular attr_id */
parser* p = HASH_TABLE(ava_type->attr_id);
/* parser has function point for network order to host
* order and visa-versa */
p->ntoh(ava_type, parsed_packet.attribute_list->data[i]);
}
Теперь мои вопросы:
- Несмотря на то, что у меня есть метод
HASH_TABLE
, описанный выше, но на самом деле я использую от 20 до 30IF-ELSE
. Так как C не имеетhash table
вstdlib
. В протоколе порядка 600, и я не хочу писать 600if-else
. Какие предложения и методы вы дадите для разбора этой структуры в соответствии с ихattribute_id
. - Другая проблема - заполнение компилятора в структурах, которые я определил. Вся моя структура определяется полем
flexible array
для контейнера данных. Теперь, когда я получаю сообщение, они содержатlength
почти для каждого атрибута, но этотlength
не может использоваться дляmalloc..ing
моей анализируемой структуры, поскольку компилятор может волшебным образом добавить несколько байтов paddings, и мне не хватает байтов. Обычно яmalloc..ing
околоlenght + 300
байт для целей безопасности. На самом деле это выглядит плохой практикой управления памятью. Любые предложения по этой проблеме?
malloc..ing
Структура для анализа полученных сообщений является самой большой проблемой для меня до сих пор. Я хочу, чтобы какая-то память была эффективной и быстрой для этого?
Кроме того, если вы уже сделали такие проекты, не могли бы вы поделиться своим подходом? Любые предложения или комментарии, чтобы поставить меня в правильном направлении? Я хочу простой дизайн, не усложняя вещи.
отправка плохих мыслей на вас для бессмысленного использования типа – tbert