TCP-пакеты обычно переупорядочиваются?

Я переопределяю старую библиотеку сетевого уровня, но на этот раз использую boost asio. Наше программное обеспечение — диалог tcpip с программным обеспечением сторонних производителей. Несколько сообщений ведут себя очень хорошо с обеих сторон, но есть один случай, который я неправильно понимаю:

Третья сторона отправляет два сообщения (сообщения A и B) одно за другим (реальное короткое время), но я получаю только часть сообщения A в tcp-пакете 1, а конец сообщения A и все сообщение B в tcp- Пакет 2. (Я нюхаю с Wireshark).

Я не думал об этом случае, мне интересно, распространено ли это с tcp, и должен ли мой уровень быть адаптивным к этому случаю — или я должен сказать третьей стороне проверить, что они делают на их стороне, чтобы я получил оба сообщение в разных пакетах.

1

Решение

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

Моя проблема с сообщением B, которое я не вижу, потому что это после конца сообщения один в том же пакете.

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

Приложение, которое отправляет через TCP, нуждается в другом способе разделения сообщений. Иногда это делается путем пометки конца каждого сообщения. Например SMTP отмечает конец сообщения следующим образом:

Передача тела почтового сообщения начинается с
Команда DATA, после которой она передается дословно, строка за строкой, и
завершается последовательностью конца данных. Эта последовательность состоит из
новая строка (), одна полная остановка (период), за которой следует
еще одна новая строка. Поскольку тело сообщения может содержать строку с
точка как часть текста, клиент отправляет два периода каждый раз
строка начинается с точки; соответственно сервер заменяет каждый
последовательность двух периодов в начале строки с одним.
Такой метод экранирования называется точечной начинкой.

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

Если вы кодируете стек TCP, то у вас будет доступ к Заголовок сообщения TCP: в поле «Смещение данных» указывается продолжительность каждого сообщения.

4

Другие решения

Да, это распространено. TCP / IP является потоковым протоколом, и ваш «логический» пакет может быть разбит на множество «физических» пакетов, поэтому клиент отвечает за сборку пакетов более высокого уровня. Кроме того, TCP / IP гарантирует правильное упорядочение, поэтому вам не нужно беспокоиться о сборке неупорядоченных пакетов.

4

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

  • если ваши сообщения имеют одинаковый размер, выполните асинхронное чтение для этого размера.
  • если они имеют разную длину, выполните асинхронное чтение для размера вашего заголовка, проанализируйте заголовок и выполните асинхронное чтение для остальной части сообщения в соответствии с заголовком.
  • если ваши сообщения имеют переменную длину и размер неизвестен, но есть определенный конечный символ или последовательность, то вы должны сохранить оставшиеся байты за этой конечной последовательностью и добавить следующее чтение к этому остатку.
3
По вопросам рекламы [email protected]