Проблема получения многоадресного трафика из нескольких групп на одном сокете - PullRequest
0 голосов
/ 29 июня 2019

Я работаю над приложением на C, которое прослушивает несколько групп многоадресной рассылки на одном сокете. Я отключаю опцию сокета: IP_MULTICAST_ALL. Сокет получает трафик от 20 разных групп многоадресной рассылки. Этот трафик поступает пакетами в сокет. Один из этих каналов публикует только одно сообщение в секунду, и здесь никаких проблем не наблюдается.

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

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

Что я видел здесь, так это то, что приложение считывает сообщение из группы, которое периодически отправляет несколько сообщений, а затем пакет сообщений из других групп (групповые группы). Сокет настроен как неблокирующий, и я получаю EAGAIN errno каждый раз, когда пакет сообщений читается из сокета, затем больше нет данных для чтения, пока сокет не получит новое сообщение от периодической группы, затем это сообщение будет прочитано и пакет других ожидающих сообщений от других групп (приложение читает только из одного сокета). Я удостоверился, что другие группы не производят больше данных, потому что я протестировал остановку других процессов для отправки большего количества данных. Таким образом, все ожидающие сообщения в этих группах уже отправлены.

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

Сначала я подумал, что это связано с IGMP или механизмом опроса (мое приложение может выполнять активное ожидание или блокировку ожидания). Ожидание блокировки реализовано с помощью неблокирующего сокета, но если для errno установлено значение EAGAIN, то приложение ожидает опроса новых сообщений. Я получаю одинаковое поведение в обеих ситуациях. Я не думаю, что это IGMP, потому что IGMP_SNOOPING выключен в коммутаторах и потому что я воспроизводлю то же поведение, используя один компьютерный шлейф для всех этих коммуникаций между процессами.

Я также воспроизвожу это поведение, используя технологии обхода ядра (не используя API ядра для работы с сетью), поэтому оно не похоже на стек TCP / IP. Используя технологии обхода ядра, у меня та же парадигма: один интерфейс сообщений, который получает весь трафик от всех групп. В этом сценарии все процессы используют этот механизм для связи, а не несколько TCP / IP и несколько обходов ядра. Модель однородна.

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

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

...