Как я должен отметить конец пакета TCP?

В клиент-серверном приложении были текстовые данные переменной длины, будет отправлен назад и вперед между клиентом и сервером, как я должен отметить конец пакета, который отправляется? Например, когда сервер получает пакетные данные от клиента, как сервер знает, что клиентский пакет был полностью получен?

Действительно ли более распространено сказать серверу полный из пакета, что это собирается получить перед данными или иметь что-то отмечающее конец пакета?

Некоторые отправленные данные только будут несколькими символами долго, и некоторые могли быть тысячами символов.

18
задан Keith Maurino 5 March 2010 в 20:32
поделиться

5 ответов

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

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

Итак, теперь у вас есть гладкий оштукатуренный TCP-туннель, и вы хотите добавить в него некоторую структуру. Вы хотите рисовать коробки, чтобы ваши рисунки были отделены друг от друга. Вот что вы хотите сделать: добавить немного «административной» структуры (рамки вокруг чертежей) к вашим данным.

Многие протоколы используют концепцию пакета , который представляет собой набор данных, начинающийся с административного заголовка фиксированного формата. Заголовок содержит достаточно информации, чтобы решить, где заканчивается пакет; например, он включает длину пакета. HTTP делает это с помощью заголовка Content-Length или (с HTTP / 1.1) с «кодированием передачи по частям», где данные разделяются на один или несколько мини-пакетов, каждый с простым заголовком, состоящим из точно указание длины мини-пакета.

Другой способ - иметь специальную последовательность терминатора, которая не может появляться в «обычных данных». Если ваши данные являются текстовыми, вы можете использовать байт с нулевым значением в качестве терминатора.

Еще один способ - использовать данные с самоограничением. Это данные, структурированные таким образом, что вы можете в любой момент узнать, достигнут ли конец элемента. Например, данные XML организованы в виде вложенных пар маркеров, таких как ... . Когда конечный маркер ( ) достигнут, вы знаете, что элемент закончен.

32
ответ дан 30 November 2019 в 07:03
поделиться

Структурируйте свой пакет таким образом, чтобы он включал поле длины в начале.

3
ответ дан 30 November 2019 в 07:03
поделиться

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

Преимущество перед маркером хвоста состоит в том, что приемник может оптимизировать ожидаемый объем данных, например выделить буфер правильного размера. Например, хранение по протоколам TCP / IP имеет ту же проблему по TCP / IP, что и вы. В этих случаях заголовки обеспечивают длину ожидаемых впоследствии данных.

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

2
ответ дан 30 November 2019 в 07:03
поделиться

Воспользуйтесь подсказками HTTP.

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

Как это делает HTTP: заголовки заканчиваются CR-LF-CR-LF. Если есть данные за заголовками, длина данных находится в одном из заголовков.

1
ответ дан 30 November 2019 в 07:03
поделиться

Если вы чувствуете себя особенно смелым, вы можете изучить использование сокетов SCTP вместо сокетов TCP.

1
ответ дан 30 November 2019 в 07:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: