Я переопределяю старую библиотеку сетевого уровня, но на этот раз использую boost asio. Наше программное обеспечение — диалог tcpip с программным обеспечением сторонних производителей. Несколько сообщений ведут себя очень хорошо с обеих сторон, но есть один случай, который я неправильно понимаю:
Третья сторона отправляет два сообщения (сообщения A и B) одно за другим (реальное короткое время), но я получаю только часть сообщения A в tcp-пакете 1, а конец сообщения A и все сообщение B в tcp- Пакет 2. (Я нюхаю с Wireshark).
Я не думал об этом случае, мне интересно, распространено ли это с tcp, и должен ли мой уровень быть адаптивным к этому случаю — или я должен сказать третьей стороне проверить, что они делают на их стороне, чтобы я получил оба сообщение в разных пакетах.
Пакеты могут быть фрагментированы и поступать не по порядку. Стек TCP, который их получает, должен их буферизовать и переупорядочить, прежде чем представлять данные в виде входящего потока на прикладном уровне.
Моя проблема с сообщением B, которое я не вижу, потому что это после конца сообщения один в том же пакете.
Вы не можете полагаться на «сообщения», имеющие однозначное сопоставление с «пакетами»: для приложения TCP (не UDP) выглядит как «потоковый» протокол.
Приложение, которое отправляет через TCP, нуждается в другом способе разделения сообщений. Иногда это делается путем пометки конца каждого сообщения. Например SMTP отмечает конец сообщения следующим образом:
Передача тела почтового сообщения начинается с
Команда DATA, после которой она передается дословно, строка за строкой, и
завершается последовательностью конца данных. Эта последовательность состоит из
новая строка (), одна полная остановка (период), за которой следует
еще одна новая строка. Поскольку тело сообщения может содержать строку с
точка как часть текста, клиент отправляет два периода каждый раз
строка начинается с точки; соответственно сервер заменяет каждый
последовательность двух периодов в начале строки с одним.
Такой метод экранирования называется точечной начинкой.
В качестве альтернативы протокол может указывать префикс в начале каждого сообщения, который будет указывать длину сообщения в байтах.
Если вы кодируете стек TCP, то у вас будет доступ к Заголовок сообщения TCP: в поле «Смещение данных» указывается продолжительность каждого сообщения.
Да, это распространено. TCP / IP является потоковым протоколом, и ваш «логический» пакет может быть разбит на множество «физических» пакетов, поэтому клиент отвечает за сборку пакетов более высокого уровня. Кроме того, TCP / IP гарантирует правильное упорядочение, поэтому вам не нужно беспокоиться о сборке неупорядоченных пакетов.
Ваша проблема не имеет ничего общего с TCP. ваша проблема в том, что вы ожидали, что asio выполнит для вас разбор сообщения. это не так, вы должны это осуществить.