Данные команд клиента / сервера TCP / IP - PullRequest
0 голосов
/ 17 августа 2011

У меня есть клиент-серверная архитектура (C # .Net 4.0), которая отправляет командные пакеты данных в виде байтовых массивов.В любой команде есть переменное число параметров, и каждый параметр имеет переменную длину.Из-за этого я использую разделители для конца параметра и команды в целом.Операнд всегда 2 байта, а оба типа разделителя - 1 байт.Последний параметр parameter_delmiter является избыточным, так как command_delmiter обеспечивает те же функциональные возможности.

Структура команды следующая:

FIELD                  SIZE(BYTES)
operand                2
parameter1             x
parameter_delmiter     1
parameter2             x
parameter_delmiter     1
parameterN             x
.............
.............
command_delmiter       1

Параметры получены из множества различных типов, т. Е. Целые числа, строки и т. Д., Все они закодированыв байтовые массивы.

У меня проблема в том, что иногда параметры при кодировании в байтовые массивы содержат байты, которые имеют то же значение, что и разделитель.Например, command_delmiter = 255 .. и у параметра может быть этот байт внутри него.

Существует три способа исправить это:

1) Кодироватьпараметры по-разному, так что они никогда не могут иметь одинаковое значение с модулем разделителя (255 и 254) ?.Это будет означать, что параметры станут больше, т. Е. Int16 будет иметь размер более 2 байтов и т. Д.

2) Ни в коем случае не используйте разделители, используйте значения количества и длины в начале структуры команды.

3) Используйте что-то еще.

Насколько мне известно, работа буферов TCP / IP заключается в том, что НЕКОТОРЫЙ СОРТ разделителя должен использоваться для разделения«команды» или «связки данных» в качестве буфера могут содержать несколько команд, или команда может охватывать несколько буферов. Так что этот

BinaryReader / Writer кажется очевидным кандидатом, единственная проблема заключается в том, что байтмассив может содержать несколько команд (с параметрами внутри).Таким образом, байтовый массив все равно должен быть обрезан для того, чтобы почувствовать его в BinaryReader.

Предложения?

Спасибо.

1 Ответ

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

Стандартный способ сделать это - указать длину сообщения в (фиксированных) первых нескольких байтах сообщения.Таким образом, у вас могут быть первые 4 байта для обозначения длины сообщения, прочитайте эти многочисленные байты для содержания сообщения.Следующие 4 байта будут длиной следующего сообщения.Длина 0 может указывать на конец сообщения.Или вы можете использовать заголовок с количеством сообщений.

Кроме того, помните, что TCP - это поток байтов, поэтому не ожидайте, что полное сообщение будет доступно каждый раз, когда вы читаете данные из сокета.Вы можете получить произвольное количество байтов при прочтении.

...