Во-первых, я знаю, что здесь много вопросов, связанных с темами многоадресной рассылки. Я также видел, что проблема большинства людей не позволяет IP_MULTICAST_LOOP
. Я уже получил это, и все еще получаю ошибку «Нет устройства».IP_ADD_MEMBERSHIP приводит к тому, что «никаких устройств не найдено», несмотря на IP_MULTICAST_LOOP (Linux, C++, UDP)
Я пишу программу, которая работает с интерфейсом loopback или с подключенными сетевыми устройствами, в зависимости от того, что пользователь делает аппаратно (подключайте или выходите из кабеля). Я использую UDP для передачи данных. Я на Linux и код на C++.
Когда сетевой кабель подключен и, скажем, eth0
работает, все в порядке (моя настройка многоадресной рассылки работает красиво). Если только lo
доступен (и запущен, в соответствии с ifconfig
), вызов
setsockopt(this->socket(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &ipmReq, sizeof(ipmReq))
терпит неудачу с -1
, в результате чего errno
не отчетности «Нет устройства найден».
Вот соответствующий кусок кода из моего MulticastEndpoint
класса:
MulticastEndpoint::MulticastEndpoint(std::string strMulticastGroup, unsigned short usPort) : m_strMulticastGroup(strMulticastGroup), m_usPort(usPort) {
this->setSocket(::socket(AF_INET, SOCK_DGRAM, 0));
memset(&m_saAddrGroup, 0, sizeof(m_saAddrGroup));
m_saAddrGroup.sin_family = AF_INET;
m_saAddrGroup.sin_addr.s_addr = inet_addr(m_strMulticastGroup.c_str());
m_saAddrGroup.sin_port = htons(m_usPort);
unsigned int unYes = 1;
bool bOK = false;
if(setsockopt(this->socket(), SOL_SOCKET, SO_REUSEADDR, &unYes, sizeof(unYes)) >= 0) {
if(setsockopt(this->socket(), IPPROTO_IP, IP_MULTICAST_LOOP, &unYes, sizeof(unYes)) >= 0) {
memset(&m_saAddrAny, 0, sizeof(m_saAddrAny));
m_saAddrAny.sin_family = AF_INET;
m_saAddrAny.sin_addr.s_addr = htonl(INADDR_ANY);
m_saAddrAny.sin_port = htons(m_usPort);
if(bind(this->socket(), (struct sockaddr*)&m_saAddrAny, sizeof(m_saAddrAny)) >= 0) {
struct ip_mreq ipmReq;
ipmReq.imr_multiaddr.s_addr = inet_addr(m_strMulticastGroup.c_str());
ipmReq.imr_interface.s_addr = htonl(INADDR_ANY);
if(setsockopt(this->socket(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &ipmReq, sizeof(ipmReq)) >= 0) {
bOK = true;
}
}
}
}
if(!bOK) {
std::cerr << strerror(errno) << std::endl;
::close(this->socket());
this->setSocket(-1);
}
std::cout << this->socket() << std::endl;
}
Класс создается с групповым адресом 224.0.0.1
и порт 2077
. Методы setSocket(int)
и socket()
представляют собой простые функции сеттера и геттера, хранящие сокет как int
в экземпляре.
У кого-нибудь есть ключ к этому поводу? Теоретически, многоадресная рассылка должна работать только с lo
, не так ли? Кроме того, может быть, многоадресный адрес общего назначения, который я использую неправильно? И насколько мне известно о сокетах linux, INADDR_ANY
должен также охватывать интерфейс loopback. Пожалуйста, поправьте меня, если это неправильно в этих обстоятельствах.
Я очень благодарен за любое просвещение.