Отправить структуру через сокеты c - PullRequest
4 голосов
/ 25 августа 2011

Я создаю приложение для чата UDP. Безопасно ли посылать C struct через c socket и на другом конце memset получать данные? Все данные в структуре nullpaded с memset, поэтому я предполагаю, что размер структуры всегда постоянен. С какими проблемами я могу столкнуться?

Как к этому подходят более опытные программисты?

Ответы [ 4 ]

6 голосов
/ 25 августа 2011

Да, это безопасно, НО мы должны предостеречь это сначала.Вы можете столкнуться с проблемой , если вы передаете ее между несопоставимыми платформами, и тогда вам нужно беспокоиться о порядке байтового упорядочения / упаковки ( среди множества других проблем, возможно * 1008)*).При этом, если вы не знаете, как это сделать, то небезопасно предполагать, что вы получите struct в том же порядке, в котором вы его отправили.

5 голосов
/ 25 августа 2011

Как бы вы ни делали, юнит-тест из этого черт побери. Компиляторы и платформы сильно различаются по этим пунктам, поэтому никогда не думайте вслепую, что они согласованы.

Компиляторы могут изменять выравнивание структуры по своему усмотрению (например, по соображениям производительности). Запросы на некоторые ограничения обычно зависят от компилятора, хотя это поддерживается MSVC и gcc (через расширение)

#pragma pack(push, 1)
struct Foo {
  // ..
};
#pragma pack(pop)

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

Если вы хотите быть полностью совместимым, то сериализуйте каждое поле самостоятельно. Это действительно не так уж много работы.

Вам также придется иметь дело с порядком байтов, как уже упоминалось другими.

3 голосов
/ 25 августа 2011

Все данные в структуре обнуляются с помощью memset, поэтому я предполагаю, что размер структуры всегда постоянен.

Это не имеет большого смысла. Объекты всегда имеют фиксированный размер. «Nullpadding с memset» не имеет к этому никакого отношения.

Безопасно ли посылать C struct через c сокет и на другом конце memset получать данные?

Нет, не совсем.

Лучше рассмотреть вопрос об отправке «данных», а не точного побайтного физического содержимого объекта в вашей памяти.

С какими проблемами я могу столкнуться?

  • заполнение элемента
  • выравнивание данных
  • Типоразмеры
  • 1028 * Порядок байтов *
  • Indirection & mdash; указатели на данные, а не на сами данные

Как к этому подходят более опытные программисты?

Лучше всего делать сериализацию правильно.

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

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

  2. Однако для простой работы вы можете просто использовать читабельный текстовый формат. Не могу ошибиться с этим.

1 голос
/ 25 августа 2011

Вы должны быть осторожны, чтобы ваша структура не содержала указателей (например, char* строки). Это применимо, когда вы сохраняете std::string также внутри структуры, потому что std::string имеет указатель внутри него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...