Попробуйте установить IP_MULTICAST_ALL в 0. По умолчанию 1. 1. 1001 *
Объяснение: При IP_MULTICAST_ALL 0 ваша ОС будет фильтровать входящие UDP-пакеты по группам, к которым вы присоединились в данный момент, что вы ожидаете в своем описании.
Но это не стандартное поведение в Linux.
По умолчанию (с IP_MULTICAST_ALL = 1) принимается любых пакетов UDP, которые поступают в ваш сокет. При назначении 0.0.0.0 это будут все UDP-пакеты, которые машина получает для этого порта, многоадресная и одноадресная, независимо от того, присоединились ли вы к какой-либо группе многоадресной рассылки или нет. Это означает, что вы увидите все артефакты разницы между присоединением к многоадресной группе и выходом из нее и реальное IGMP-сообщение, отправленное вашей машиной, а также вы увидите все артефакты и ошибки всех маршрутизаторов и коммутаторов, которые есть в вашей локальной сети. Например, когда вы покидаете группу многоадресной рассылки, ваша ОС может решить вообще не отправлять соответствующее сообщение IGMP, например, из-за того, что какой-то другой сокет также прослушивает этот адрес многоадресной рассылки, или из-за того, что ОС решает выйти с задержкой. Это все вполне допустимо.
Кстати, когда вы связываетесь с многоадресным адресом в Linux, у него просто есть функция фильтрации и вообще нет функции привязки. После этого вы будете получать только пакеты UDP, предназначенные для этого конкретного IP-адреса многоадресной рассылки, независимо от того, присоединились ли вы также к другим группам многоадресной рассылки.
Относительно «очистки» сокета. Очереди пакетов за сокетом полностью выходят за рамки вашего приложения. Вы не можете влиять на состояние или поведение очереди (кроме чтения из очереди или нет) и не можете ожидать какого-либо конкретного поведения.
На практике я бы предложил:
- Привязать к 0.0.0.0.
- Присоединяйтесь и выходите из групп многоадресной рассылки соответствующим образом.
- Проверьте целевой адрес каждого полученного вами UDP-пакета и выполните фильтрацию самостоятельно. Используйте IP_PKTINFO, чтобы получить адрес назначения для каждого пакета.
- Ни в коем случае не полагайтесь на маршрутизаторы и коммутаторы, имеющие какое-либо явное и детерминированное поведение многоадресной маршрутизации. У большинства из них есть минутные перерывы для выхода из групп многоадресной рассылки. Это означает, что даже когда вы покинули многоадресную группу (и даже если вы не присоединились), вы можете продолжать получать многоадресный трафик в течение нескольких минут. Это маскирует ошибки в вашем коде и вызывает головную боль при попытке отладки.
Таким образом, вам не придется полагаться на поведение, зависящее от ОС, и вы полностью контролируете, что вы получаете, а что нет.