C - Как определить количество байтов для сообщений JSON - PullRequest
0 голосов
/ 14 мая 2018

Я работаю над проектом на основе Linux, состоящим из «основного» приложения, написанного на C, и веб-сервера, возможно, написанного на Python. Ядро и веб-сервер должны иметь возможность общаться друг с другом через TCP / IP. Я сосредоточен на основном приложении, на языке C.

Из-за различных языков программирования, используемых для ядра и веб-сервера, я ищу протокол сообщений, который прост в использовании на обоих языках. В настоящее время я считаю JSON хорошим кандидатом. Мой вопрос, однако, не столько о протоколе сообщений, сколько о том, как определить количество байтов для чтения (и, возможно, отправки) в сокет, особенно при использовании протокола сообщений, такого как JSON или XML.

Насколько я понимаю, независимо от того, используете ли вы JSON, XML или какой-либо другой протокол сообщений, вы не можете включать размер сообщения в само сообщение, потому что для разбора сообщения вам потребуется все сообщение и, следовательно, Нужно знать размер его заранее. Обратите внимание, что под «сообщением» я подразумеваю данные, отформатированные в соответствии с используемым протоколом сообщений.

Я размышлял и читал о решении этой проблемы и пришел к следующим двум возможностям:

  1. Определите максимально возможный размер сообщения, скажем, 500 байт, и на основе этого определите размер буфера, скажем, 512 байт, и добавьте дополнение к каждому сообщению, чтобы отправлять 512 байт;
  2. Добавить каждое сообщение с его размером в «обычном тексте». Если размер хранится в Int (4 байта), то получатель сначала читает 4 байта из сокета и, используя эти 4 байта, определяет, сколько байтов следует читать для текущего сообщения;

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

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

С уважением.

1 Ответ

0 голосов
/ 14 мая 2018

Это классическая проблема, с которой сталкиваются потоки, в том числе TCP, часто называемые «проблемой границы сообщения».Вы можете найти более подробные ответы, чем те, которые я могу дать здесь.

Чтобы определить границы, у вас есть несколько вариантов:

  • Фиксированная длина с отступом, как вы сказали.Если у вас нет очень маленьких сообщений, не рекомендуется.
  • Подготовьте размер, как вы сказали.Если вы хотите получать модные сообщения и поддерживать большие сообщения, не тратя слишком много байтов, вы можете использовать количество переменной длины, где вы используете бит, чтобы определить, следует ли читать больше байтов для размера.@alnitak упомянул о недостатке в комментариях, которыми я пренебрегал, а именно, что вы не можете начать отправку, пока не узнаете размер.
  • Связан с некоторым байтом, который вы нигде больше не используете (JSON и XML являются текстовымитолько '\ 0' работает с ASCII или любым UTF).Просто, но медленнее на принимающей стороне, потому что вы должны сканировать каждый байт таким образом.
  • Редактировать: JSON, XML и многие другие форматы также могут быть проанализированы на лету для определения границ (например, каждый { должен быть закрыт с } в JSON), но я не вижу никакого преимущества в этом.

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

Исправления: я изначально говорил что-то совершенно неправильное о необходимости включать контрольную сумму для обработки потери пакетов, несмотря на TCP ... TCP не будет продвигатьсяпока эти пакеты не будут приняты должным образом, так что это не проблема.ИДК, о чем я думал.

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