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

0
pthien 14 Янв 2021 в 00:05

1 ответ

Лучший ответ

Предполагая, что вы используете Linux, при получении как одноадресного, так и многоадресного трафика в один и тот же сокет вы должны привязаться к INADDR_ANY, то есть 0.0.0.0. Если вы привяжетесь к определенному интерфейсу, вы не получите многоадресный трафик, а если вы привяжетесь к многоадресному адресу, вы не получите одноадресный трафик.

Итак, настройте свой адрес привязки следующим образом:

memset((char*) &locakSocket, 0, sizeof(localSocket));
localSocket.sin_family = AF_INET;
localSocket.sin_port = htons(port);
localSocket.sin_addr.s_addr = INADDR_ANY;

Вы также не хотите использовать SO_REUSEADDR или SO_REUSEPORT. При приеме многоадресной рассылки он позволяет вам иметь два открытых сокета на одном и том же порте, которые будут получать многоадресный трафик, однако точно не определено, идет ли одноадресный трафик на оба, только на один или циклический. Вам также не нужен SO_BROADCAST в приемнике, поскольку он контролирует только исходящие дейтаграммы, отправленные на широковещательный адрес (например, x.x.x.255).

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

Кроме того, как упоминалось в комментариях, вы должны использовать recvfrom для получения данных из сокета UDP. Это позволяет вам получить IP / порт источника входящей дейтаграммы, а также позволяет при необходимости устанавливать специфичные для сокета флаги.

0
dbush 14 Янв 2021 в 14:11