saide_a Ответов: 2

C++ потерял UDP-пакеты, которые в реальном времени задерживаются


У меня есть UDP-соединение, которое соединяет эхо-сервер с тестовым клиентом. тестовый клиент непрерывно отправляет пакеты и ожидает их получения около секунды.
если он не может получить пакет, предполагает, что пакет потерян и отправляет другой пакет.
Большинство пакетов отправляются и принимаются успешно, но некоторые из них, которые предполагаются потерянными, будут получены в клиенте после отправки следующего пакета. на самом деле они принимаются с опозданием.
что я могу сделать для устранения этих задержанных пакетов?
(моя программа работает на моем локальном хосте - так что потеря пакетов не является разумной)

Что я уже пробовал:

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

Richard MacCutchan

UDP по определению ненадежен, поэтому пакеты могут быть получены не по порядку или просто потеряны. Если вы хотите надежную связь, то переключитесь на TCP.

2 Ответов

Рейтинг:
20

Jochen Arndt

При использовании localhost (loopback) не должно быть никаких потерянных пакетов и никакой значительной задержки. Таким образом, проблема может быть вызвана вашей реализацией (вероятно, серверным кодом, который обрабатывает прием).

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

Если вы хотите использовать код позже с нелокальными системами и должны обнаруживать потерянные пакеты или обрабатывать неупорядоченный прием, вы должны реализовать какой-то вид отслеживания пакетов. Тогда, возможно, было бы лучше использовать TCP вместо этого, как уже предлагал Ричард.


saide_a

Я уверен, что клиентский пакет отправляет и в то же время в echo server я получаю ошибку socket receive time out, я не потерял, но несколько пакетов задерживаются.
Мой код-event dirven

Jochen Arndt

Насколько я понимаю:
- Клиент отправляет
- Сервер получает и отправляет обратно
- Клиент получает

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

Вопрос:
Почему вы получили ошибку тайм-аута при использовании событийного приема?
Вы пытаетесь прочитать больше байтов, чем доступно?

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

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

Но ответить подробно, не увидев соответствующего кода, невозможно.

Вы можете использовать зеленую ссылку "улучшить вопрос", чтобы добавить дополнительную информацию к вашему вопросу (даже информация об ошибке тайм-аута важна и должна была быть там изначально).

Рейтинг:
0

KarstenK

Как все писали, использование TCP в этом случае лучше.

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