Как разделить сообщения сокета TCP - PullRequest
5 голосов
/ 06 декабря 2010

Я немного поэкспериментировал с асинхронными сообщениями сокетов TCP между двумя программами для передачи данных, чисел и / или текста.Я использовал ключевое слово в начале каждого сообщения, а затем разделял значения символом «|».персонаж.Таким образом, сообщение может выглядеть так:

"DATA | 490 | 40517.9328222222 | 1 | 6 | 11345 | 11347 | 11344 | 11345 | 106 | 40517.8494212963"

Я установил размер буфера чтения на1024, так как большинство сообщений будет в пределах этой длины.Однако иногда я могу быстро отправить много коротких сообщений, в которых несколько вместе содержат менее 1024 символов, и кажется, что это будет прочитано за один раз.И если я отправлю сообщение длиной более 1024 символов, оно будет разбито.Поэтому я ищу несколько советов о том, как справиться с этим.Должен ли я использовать некоторые специальные символы для начала и / или окончания каждого сообщения?Буду признателен за несколько советов о том, как вы это делаете ..

Ответы [ 6 ]

5 голосов
/ 06 декабря 2010

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

Это может помочь вашему ресиверу также эффективно распределить свой приемный буфер.

3 голосов
/ 06 декабря 2010

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

00015MESSAGE|1|2 ...

Важно, чтобы поле размера имело фиксированный размер.

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

2 голосов
/ 06 декабря 2010

Существует несколько подходов.

  1. Длинное слово с префиксом к каждому сообщению.

  2. Обтекание каждого сообщения в стиле STX / ETXтак что вы можете увидеть, где он начинается и заканчивается.Это требует экранирования байтов ETX, которые встречаются в данных, а это, в свою очередь, требует экранирования байтов ESC.

  3. Протокол с самоописанием, например XML, или длина типапротокол на основе значений.

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

Протокол это все. Для моего приложения чата я использую протокол аргументов, например, когда вы запускаете

shutdown.exe -s -f -t 30

Но тогда для сокетов я использую это

join John%20Doe            ' %20 for space
msg This%20Is%20a%20test   ' again %20 for space

Таким образом, не имеет значения, отправляются ли ваши данные ASYNC: D Надеюсь, это поможет

0 голосов
/ 06 декабря 2010

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

Tar, очевидно, не является приложением TCP, но имеет аналогичный анализ данныхтребования к обработке.

Также Ваш размер меньше 512 байт, но, возможно, имеет смысл включить 64-байтовый блок, или 128 или что-то еще, и отправить все ваши данные в пакетах такого размера.вы теряете эффективность из-за издержек «размера блока», но вы можете повысить эффективность и простоту алгоритма обработки данных.

0 голосов
/ 06 декабря 2010

Вы можете решить эту проблему, дополнив свои сообщения уникальными байтами (например, 255, которые не отображаются в ASCII) до размера буфера и распакуйте их на принимающей стороне. Для меня это не очень хорошее и умное решение, но оно действительно работает.

Или вы можете попытаться отправить общую длину пакета в начале каждого пакета, что является более броским вызовом и работает более эффективно как метод заполнения, когда все сделано правильно. Объединенные пакеты будут выглядеть примерно так (схема):

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