Здесь 192.168.2.2 — IP интерфейса eth1.
239.255.0.1 — IP группы
30001 — порт группы
boost::asio::ip::udp::socket socket_;
boost::asio::ip::udp::endpoint sender_endpoint_;
std::vector<uint8_t> inputData;
Подскажите, что может быть не так, как найти причину, почему через boost asio ничего не приходит?
Первое: почему свой локальный айпишник для бинда, ведь мультикаст адресуется не на "192.168.2.2", а на "239.255.0.1"? Попробуйте INADDR_ANY для 100% гарантии.
Второе: по дефолту мультикаст прилетает только на один интерфейс — и не факт что система выберет именно 192.168.2.2. Когда делаем join_group — нет ли там у asio перегрузки для двух аргументов: адрес группы и адрес своего интерфейса? Потому как у олдскульного API там два параметра:
Members
imr_multiaddr
The address of the IPv4 multicast group.
imr_interface
The local IPv4 address of the interface or the interface index on which the multicast group should be joined or dropped. This value is in network byte order. If this member specifies an IPv4 address of 0.0.0.0, the default IPv4 multicast interface is used.
Здравствуйте, prrt, Вы писали:
P>Да, действительно...
P>Исправил: P>И всё-равно ничего не получает. Прямо беда какая-то, хоть в исходниках tcpdump ковыряйся, чтобы оттуда нужный код взять, ведь он-то работает...
Я бы рекомендовал для начала нарисовать минимальный пример на обычных беркли-сокетах, безо всякого asio. Или всё же на asio, но запускать в случае если одна сетевуха в машине. Есть подозрение, что мультикаст асиошники сделали "шоб было", без учёта ряда факторов (типа мультихоминга, ipv6 и прочее).
Здравствуйте, Mr.Delphist, Вы писали:
MD>Я бы рекомендовал для начала нарисовать минимальный пример на обычных беркли-сокетах, безо всякого asio.
А Вы не посоветуете какой-нибудь подобный пример? Наверняка должны быть готовые решения. Я погуглил, но то, что нашел, тоже не заработало (вечное ожидание данных), например:
Проверять могу только на машине с несколькими интерфейсами, на которые поступают разные данные. При этом сам UDP поток изменять не могу, он поступает на один из этих интерфейсов.
Здравствуйте, prrt, Вы писали:
P>Здравствуйте, Mr.Delphist, Вы писали:
MD>>Я бы рекомендовал для начала нарисовать минимальный пример на обычных беркли-сокетах, безо всякого asio.
P>А Вы не посоветуете какой-нибудь подобный пример? Наверняка должны быть готовые решения. Я погуглил, но то, что нашел, тоже не заработало (вечное ожидание данных), например:
Спасибо! Скомпилировал, запустил клиент. При запуске выдаёт:
setsockopt(IP_ADD_MEMBERSHIP): No such device
Почитал, такая ошибка означает, что либо ядро скомпилировано без поддержки мультикаста, либо не прописан роутинг для мультикаст трафика. Первое исключается, т.к. tcpdump работает. Для второго сделал:
# route add -net 224.0.0.0 netmask 240.0.0.0 eth1
Но всё равно не помогло, та же ошибка. Что же здесь еще может быть такое?
Хотя такая ошибка возникает только в случае, если указать интерфейс, т.е. запускать клиент с опцией --miface=eth1. Если эту опцию убрать, то запускается нормально, но данные уже не получает, опять вечный цикл ожидания...
P>>setsockopt(IP_ADD_MEMBERSHIP): No such device
P>Хотя такая ошибка возникает только в случае, если указать интерфейс, т.е. запускать клиент с опцией --miface=eth1. Если эту опцию убрать, то запускается нормально, но данные уже не получает, опять вечный цикл ожидания...
надо не eth0 указывать,а его ipv4 адрес
например --miface=192.168.1.2
route у меня эти маршруты не прописывет
и по умолчанию достаточно запустить mcast-client и mcast-server без параметров что бы они увидели друг друга
Здравствуйте, prrt, Вы писали:
P>Здравствуйте, Mr.Delphist, Вы писали:
MD>>Я бы рекомендовал для начала нарисовать минимальный пример на обычных беркли-сокетах, безо всякого asio.
P>А Вы не посоветуете какой-нибудь подобный пример? Наверняка должны быть готовые решения. Я погуглил, но то, что нашел, тоже не заработало (вечное ожидание данных), например:
Можно для экспериментов брать порт 1900 — это протокол upnp, трафик по нему есть в любой сетке, в wireshark он показывается зелёненьким цветом
Здравствуйте, kov_serg, Вы писали:
_>надо не eth0 указывать,а его ipv4 адрес _>например --miface=192.168.1.2
_>route у меня эти маршруты не прописывет
_>и по умолчанию достаточно запустить mcast-client и mcast-server без параметров что бы они увидели друг друга
Исправил, задал локальный IP интерфейса, в итоге тоже ничего опять не получает. С mcast-server оно наверняка заработает, т.к. у меня и с Asio всё работает, если пакеты отправлять тоже через Asio, и ловить им же. Не работает именно с этим хитрым трафиком, на этом интерфейсе.
Начал ковырять tcpdump. Похоже, он читает данные с интерфейса как с файла устройства. Меня этот вариант вполне бы устроил, парсинг raw данных можно сделать и на прикладном уровне. Вот только /dev/ethX отсутствуют, в итоге непонятно, как прочитать данные с интерфейса как файла устройства?
Здравствуйте, Mr.Delphist, Вы писали:
MD>Можно для экспериментов брать порт 1900 — это протокол upnp, трафик по нему есть в любой сетке, в wireshark он показывается зелёненьким цветом
В моём случае на этом порту данных нет. Т.к. это даже не сетка, а выделенный кабель на который поступают только те данные, которые мне и нужно ловить. tcpdump тоже показал, что на 1900 порту ничего нет.
Здравствуйте, prrt, Вы писали:
P>Здравствуйте, kov_serg, Вы писали:
_>>надо не eth0 указывать,а его ipv4 адрес _>>например --miface=192.168.1.2
_>>route у меня эти маршруты не прописывет
_>>и по умолчанию достаточно запустить mcast-client и mcast-server без параметров что бы они увидели друг друга
P>Исправил, задал локальный IP интерфейса, в итоге тоже ничего опять не получает. С mcast-server оно наверняка заработает, т.к. у меня и с Asio всё работает, если пакеты отправлять тоже через Asio, и ловить им же. Не работает именно с этим хитрым трафиком, на этом интерфейсе.
P>Начал ковырять tcpdump. Похоже, он читает данные с интерфейса как с файла устройства. Меня этот вариант вполне бы устроил, парсинг raw данных можно сделать и на прикладном уровне. Вот только /dev/ethX отсутствуют, в итоге непонятно, как прочитать данные с интерфейса как файла устройства?
Здравствуйте, prrt, Вы писали:
P>Почитал, такая ошибка означает, что либо ядро скомпилировано без поддержки мультикаста, либо не прописан роутинг для мультикаст трафика. Первое исключается, т.к. tcpdump работает.
tcpdump снимает полный поток с карты, он не получает multicast, так что на него я бы не расчитывал.
P>Для второго сделал: P># route add -net 224.0.0.0 netmask 240.0.0.0 eth1
Это исходящий маршрут по-умолчанию. Если ты указываешь интерфейс, то оно рояли не и грает. Впрочем, ты и не отправляешь ничего.
Здравствуйте, prrt, Вы писали:
P>В моём случае на этом порту данных нет. Т.к. это даже не сетка, а выделенный кабель на который поступают только те данные, которые мне и нужно ловить. tcpdump тоже показал, что на 1900 порту ничего нет.
Т.е. это прямое подключение?
Тогда это может быть и немультикаст вовсе. Приведи пример заголовка какого-нибудь пакета с этого интерфейса.
Некоторые бульбуляторы вообще могут некорректные заголовки отправлять.
Да и IP_ADD_MEMBERSHIP в этом случае сомнителен, т.к. вряд ли на устройстве есть что-то, что ответит на igmp report.
Здравствуйте, prrt, Вы писали:
P>В моём случае на этом порту данных нет. Т.к. это даже не сетка, а выделенный кабель на который поступают только те данные, которые мне и нужно ловить. tcpdump тоже показал, что на 1900 порту ничего нет.
Вот я и предлагаю сначала потренироваться "на кошках" — хоть на своей девелоперской машине. Добиться устойчивого приёма мультикастов на примере upnp:
1) два инстанса приложения слушают один и тот же стрим
2) поднимаем VPN или второй сетевой интерфейс — проверяем, что работа с мультикастами продолжается (т.к. обычно vpn считается более приоритетным, то становится "дефолтным ухом" для приёма мультикастов).
Хорошие ссылки. Только по первым двум нигде не увидел, как задавать интерфейс, который будем слушать. Использование IP вместо интерфейса как-то не особо доверие вызывает...
А вот в pcap — там да, это есть. Похоже, всё через pcap и буду делать.
Здравствуйте, andrey.desman, Вы писали:
AD>Т.е. это прямое подключение?
Да. AD>Тогда это может быть и немультикаст вовсе. Приведи пример заголовка какого-нибудь пакета с этого интерфейса.
Похоже на то. Должна ли в мультикасте быть какая-то обратная связь? Должно что-то посылаться от меня к тому, кто вещает? Если да, то это точно не мультикаст. Т.к. в обратную сторону ничего не должно идти, это было четко сказано.
С пакетами как разберусь, пример приведу. Чтобы по шапке не получить, что какую-нибудь закрытую информацию оглашу
AD>Некоторые бульбуляторы вообще могут некорректные заголовки отправлять.
AD>Да и IP_ADD_MEMBERSHIP в этом случае сомнителен, т.к. вряд ли на устройстве есть что-то, что ответит на igmp report.
Всё-таки, видимо, это не мультикаст. Поставил в tcpdump режим non-promiscuous, и он сразу перестал ловить трафик. Так что, наверное, здесь только с pcap надо делать.
Здравствуйте, prrt, Вы писали:
P>Похоже на то. Должна ли в мультикасте быть какая-то обратная связь? Должно что-то посылаться от меня к тому, кто вещает? Если да, то это точно не мультикаст. Т.к. в обратную сторону ничего не должно идти, это было четко сказано.
С одной сторны, тебе надо указать данные какой группы ты хочешь получать, иначе ядро будет игнорировать эти пакеты. С другой стороны, ядро пошлет igmp report, чтобы подписаться на группу. Насколько эта отправка критична для этого устройства х.з. Но на этом в принципе коммуникация в сторону устройства закончится.
Здравствуйте, prrt, Вы писали:
P>Всё-таки, видимо, это не мультикаст. Поставил в tcpdump режим non-promiscuous, и он сразу перестал ловить трафик. Так что, наверное, здесь только с pcap надо делать.
Возможно, устройство отправляет не на широковещательный MAC, а на какой-то хардкод. Сложно сказать, не видя заголовка пакета.
А ты пробовал сишные примеры запускать в промиск режиме?
Здравствуйте, andrey.desman, Вы писали:
AD>А ты пробовал сишные примеры запускать в промиск режиме?
Хорошая идея. Попробовал. Использовал вот этот код — https://gist.github.com/austinmarton/2862515
Пакеты получает, всё ок. Но что странно — он их получает даже в случае, если задаю другой интерфейс. И наоборот — слушаю нужный интерфейс, а кроме нужных пакетов, получаю и пакеты со своим собственным IP в качестве Source IP, т.е. как я понимаю, это мой собственный ssh трафик (на сервере работаю удаленно, захожу через второй интерфейс).
Это наводит на подозрения, что таким образом я буду получать вообще весь трафик со всех интерфейсов...
Я имел в виду мультикастовые примеры в промиск режиме. Впрочем, может так и проще даже будет.
P>Пакеты получает, всё ок. Но что странно — он их получает даже в случае, если задаю другой интерфейс. И наоборот — слушаю нужный интерфейс, а кроме нужных пакетов, получаю и пакеты со своим собственным IP в качестве Source IP, т.е. как я понимаю, это мой собственный ssh трафик (на сервере работаю удаленно, захожу через второй интерфейс). P>Это наводит на подозрения, что таким образом я буду получать вообще весь трафик со всех интерфейсов...
Так это...
https://linux.die.net/man/7/socket
SO_BINDTODEVICE
Note that this only works for some socket types, particularly AF_INET sockets. It is not supported for packet sockets (use normal bind(2) there).
Здравствуйте, andrey.desman, Вы писали:
AD>Я имел в виду мультикастовые примеры в промиск режиме. Впрочем, может так и проще даже будет.
AD>Надо через bind() к интерфейсу привязываться.
Через bind() всё получилось, пошли пакеты на приём с нужного этого интерфейса. Ну и хоть без pcap заработало, не придется тянуть зависимость, да и так проще вышло.
Мульткастовый пример проверил в промиск режиме — не работает, не получает ничего.