2010-10-07 5 views
0

Хорошо, я ненавижу задавать этот вопрос ... но здесь идет. Я пишу код на C на машине x86. Я хочу отправить структуру по сети, и я хочу преобразовать структуру в Сетевой порядок байтов ... Я понимаю всю драму о упаковке и прагмах упаковки gcc ... то, что я хочу знать, это КАК я конвертирую структуру (или массив или любую такую ​​произвольную память) для сетевого байтового порядка.Byte swapping a struct

Есть ли стандартный (Unix/Linux/Posix) вызов функции, который я могу использовать, или я должен использовать его самостоятельно.

х

+0

Вкратце ... если у меня есть структура ..., которая выглядит как эта структура {int a; int arrayx [200]; } mystruct_t; ... может ли это быть чисто байт заменен? – Xofo

ответ

7

В принципе, вы можете пройти через структуры и вызвать htonl или htons на каждом uint32_t или uint16_t поле, соответственно, присваивая результаты обратно или копию структура. Однако я бы не рекомендовал такой подход. Он очень хрупок и подвержен проблемам выравнивания структуры и т. Д.

Если данные передачи и приема не являются критическими для производительности, я бы просто применил соответствующие методы сериализации и десериализации для ваших структур. Вы можете писать числовые значения за один байт за раз в двоичном формате, выбирая, хотите ли вы сначала записать наименее значимую или наиболее значимую часть. Но на самом деле, я бы рекомендовал выбрать современный текстовый формат сериализации, такой как json или (uhg, я ненавижу сказать это) xml. Стоимость сериализации и десериализации текста довольно мала, и преимущества с точки зрения легкости и расширяемости отладки значительны.

Наконец, если вы хотите использовать текст, но найти JSON или XML слишком неприятной, слишком тяжелой или слишком много кривой обучения, вы всегда можете просто использовать printf и scanf форматирования для чтения и записи структуры как текст в фиксированной заказ. Написание всех числовых значений, включая поплавки, в шестнадцатеричном, а не в десятичном формате, вероятно, немного улучшит производительность и обеспечит точность округления с плавающей точкой. Если у вас нет C99, другой вариант для поплавков может состоять в том, чтобы разложить их на форму мантиссы/экспоненты и перекомпонировать их, используя frexp и ldexp.

+0

Согласитесь, но я все равно избегал бы текста. Если ваш код будет работать по обеим сторонам трубы, на самом деле очень легко заставить его работать, используя только двоичные данные. Просто позаботьтесь о выравнивании ('#pragma pack (1)') и фактической точности потока данных (и не забудьте также исправить плавающие типы). – ruslik

+0

реквизит для ненависти, чтобы сказать XML. переключение на текст является педантичным, но в большинстве случаев намного лучше –

+3

'#pragma pack' не удаленно переносится, а компиляторы для архитектур, в которых невозможно выполнить выравнивание доступа, пришлось бы в полной мере реализовать его. Если вы пишете структуры, отправляемые по сети в двоичной форме, вы должны просто использовать типы фиксированного размера размером 1, 2 или 4 байта и заказывать их так, чтобы даже если каждый из них требовал выравнивания, равного их размеру , отступов не будет. –

0

ОТВЕТ: Благодарим вас за ответы. Я думаю, правильный ответ заключается в том, что для структур, массивов и таких блоков памяти вы ДОЛЖНЫ реализовать свою собственную функцию сериализации ... это прекрасно ... Я рассмотрю это. Я хотел бы получить хорошее чувство, прежде чем я попытался такой вещью ...

х

+0

Я пойму, как удалить мой MPD ... – Xofo

0

Также смотрите в рамки, которые были осуществлены для решения этой точной задачи, что позволит вам Маршалл/demarshall произвольно сложным структурам данных , Если вы собираетесь делать это в масштабе, превышающем несколько типов, используйте фреймворк.

  1. rpcgen/XDR: Не давайте все разговоры о RPC/клиент/сервер отпугнуть. Вы можете использовать rpcgen для генерации XDR-алгоритмов маршаллинга/демаршаллинга для ваших данных, которые вы можете транспортировать в зависимости от того, что вам нравится.
  2. Flick IDL Compiler Kit
  3. CORBA: Большинство каркасов CORBA имеют компиляторы IDL, например. ACE TAO.
  4. ASN.1: Если вам нравится какая-то боль. Очень экзотично.
+0

Я бы добавил protobuf-c :-) – jweyrich

+0

tpl too http://tpl.sourceforge.net/ или c11n http://s11n.net/c11n/ – Xofo