Отправлять и получать многоадресные пакеты UDP с одним и тем же сокетом - PullRequest
3 голосов
/ 26 марта 2020

Я не смог найти рабочий пример для этого, поэтому я собираюсь опубликовать вопрос (и давайте посмотрим, смогу ли я свести это к примеру кода MVP). Итак, мне нужно выполнить mdns-запросы, я могу использовать два сокета (один для отправки / второй для получения), но до сих пор я не смог заставить его работать с одним сокетом.

Так что шаги, которые Я выполняю:

Перечислите все адреса интерфейса на хосте. Затем для каждого хоста:

  1. Создайте неблокирующий сокет UDP
  2. bind () либо с адресом интерфейса: 5353, либо с адресом группы многоадресной рассылки (любой из них вызывает чтение или запись). ошибка)
  3. Установите IP_MULTICAST_IF для локального интерфейса
  4. IP_ADD_MEMBERSHIP для группы многоадресной рассылки
  5. Добавьте сокеты для чтения / записи в kqueue

Таким образом, в зависимости от того, что я делаю на шаге 2, либо чтение, либо запись завершается неудачно:

  1. Если я связываю сокет с группой многоадресной рассылки, я получаю уведомления о чтении из kqueue и могу читать пакеты, но когда получаю записать уведомление из kqueue и попытаться записать его с ошибкой с ошибкой 49
  2. Если я привязываю сокет к адресу интерфейса, я могу отправлять пакеты, но из kqueue
* не приходят уведомления о прочтении 1026 * Так с каким адресом мне нужно связаться? Кроме того, поскольку параметр IP_ADD_MEMBERSHIP ip_mreq имеет поле интерфейса, действительно ли мне нужен IP_MULTICAST_IF?

1 Ответ

5 голосов
/ 26 марта 2020

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

Что вам нужно сделать, это связать с INADDR_ANY, затем, когда вы устанавливаете опцию IP_ADD_MEMBERSHIP, вы устанавливаете нужный интерфейсный адрес. получать многоадресные пакеты. Если у вас есть несколько интерфейсов, вы можете вызывать это для каждого интерфейса, к которому хотите привязаться.

...