Программирование сокетов на C и десериализация ответа - PullRequest
0 голосов
/ 26 марта 2012

Я пишу программу для связи с определенным монитором пациента с использованием сокетов без соединения (UDP). Мне нужно предложение самого быстрого и эффективного алгоритма, который я должен использовать для анализа данных, полученных с монитора пациента.

Монитор пациента отправляет данные в виде структуры AttributeList, определение структуры приведено ниже: -

typedef struct {
  uint16 count;
  uint16 length;
  AVAType * values;
} AttributeList;

typdef struct {
  uint16 id;
  uint16 length;
  void * data;
} AVAType

Таким образом, AttributeList содержит много структур AVAType, и каждая структура AVAType содержит идентификатор и данные в качестве пустого указателя (данные являются просто заполнителями для фактических данных в AVAType). На самом деле для AVAType определено около 150 идентификаторов, и для каждого идентификатора данные должны быть помещены в некоторую соответствующую структуру данных для анализа.

Таким образом, если идентификатор в структуре AVAType равен 1, данные должны быть проанализированы с использованием алгоритма A, но если идентификатор равен 2, данные должны быть проанализированы с использованием алгоритма B и т. Д. ...

Мой текущий подход заключается в использовании 150 операторов if-else и загрузке конкретной структуры данных для AVAType и последующем анализе результата. Также монитор пациента отправляет данные в порядке байтов сети, и мне нужно распаковать AVAType согласно идентификатору.

Пожалуйста, предложите хороший подход для решения этой ситуации. Это всего лишь университетская штука, я не особо беспокоюсь о безопасности, я думаю, что безопасность можно улучшить постепенно, но сейчас я беспокоюсь о скорости.

Да, это на самом деле значения AVAType [] ;. Можете ли вы быть более конкретным, почему это отличается от AVAType *? Может ли это быть полезным, если я определю свою структуру иначе?

1 Ответ

8 голосов
/ 26 марта 2012

Обычный способ отобразить целые числа на функции - это просто массив указателей на функции

typedef void (*Fun_ptr)(int id, void *current_byte);

Fun_ptr fun_ptr[0xFFFF+1] = { funcA, funcB, ...};

Если бы идентификаторы были только одним байтом, я бы отобразил все 256 (если это можно ограничить).

Даже со всеми 16-битными идентификаторами, это не много места для хранения.

Я бы указывал неиспользуемые идентификаторы на функцию «перехвата ошибок».

Использование:

next_buffer_position = fun_ptr[id](id, current_buffer_position);

Тогда функция знает, для какого идентификатора она была вызвана, что облегчает написание функции error_catch, вам нужен только один.


Вы уверены, что это AVAType * values; и void * data;?
values или data должно быть смещением в пакете?
Это не невозможно и может быть правильным. В настоящее время AVAType и AttributeList имеют фиксированный размер.

Поля AVAType * values; и void * data; - это размер принимающих компьютеров для указателя. Это может быть что угодно, но, скорее всего, 32 или 64 бит. Это потенциальная проблема, если вы перемещаете программное обеспечение на разные машины, и именно поэтому я спрашиваю. Они не содержат данных, они являются указателями на данные, но их размер варьируется в зависимости от принимающей машины. Suspicous. Дважды проверьте, какой размер они определены.

Распространенным способом обработки пакетов по сетевому протоколу является использование пустого массива в качестве последнего поля в структуре, например,

typdef struct {
  uint16 id;
  uint16 length;
  unsigned char data[];
} AVAType;

В этом подходе обычно есть длина пакета в фиксированной позиции около начала пакета, и это дает фактический размер оставшейся части пакета. Таким образом, протокол определяет, является ли весь пакет или data[] байтами длины. Это немного "хакерский", но он прост в использовании. (NB IIRC unsigned char data[]; не является законным C ++)

Резюме: Скорее всего, структуры в памяти - это именно те определения типов, которые вы показали, но протокол на проводе немного странный из-за переменного размера указателя.

...