Кажется, что ошибка в реализации MulticastReceiver.Дублирующие пакеты в многоадресном приемнике Socket
При создании двух экземпляров для < 224.0.25.46,13001> и < 224.0.25.172,13001>, я получаю каждый пакет дважды в каждом потоке. Любые указатели? Мое предположение - REUSEADDR?
class MulticastReceiverSocket {
protected:
const std::string listen_ip_;
const int listen_port_;
int socket_file_descriptor_;
public:
MulticastReceiverSocket (const std::string & listen_ip,
const int listen_port)
: listen_ip_ (listen_ip), listen_port_ (listen_port),
socket_file_descriptor_ (-1)
{
/* create socket to join multicast group on */
socket_file_descriptor_ = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (socket_file_descriptor_ < 0)
{ exit(1); }
/* set reuse port to on to allow multiple binds per host */
{
int flag_on = 1;
if ((setsockopt (socket_file_descriptor_, SOL_SOCKET,
SO_REUSEADDR, &flag_on,
sizeof(flag_on))) < 0)
{ exit(1); }
}
McastJoin ();
{
/* construct a multicast address structure */
struct sockaddr_in mcast_Addr;
bzero (&mcast_Addr, sizeof(mcast_Addr));
mcast_Addr.sin_family = AF_INET;
mcast_Addr.sin_addr.s_addr = htonl(INADDR_ANY);
mcast_Addr.sin_port = htons (listen_port_);
/* bind to specified port onany interface */
if (bind (socket_file_descriptor_, (struct sockaddr *) &mcast_Addr, sizeof (struct sockaddr_in)) < 0)
{ exit(1); }
}
}
void McastJoin ()
{
/* construct an IGMP join request structure */
struct ip_mreq mc_req;
inet_pton (AF_INET, listen_ip_.c_str(), &(mc_req.imr_multiaddr.s_addr));
mc_req.imr_interface.s_addr = htonl(INADDR_ANY);
/* send an ADD MEMBERSHIP message via setsockopt */
if ((setsockopt (socket_file_descriptor_, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(void*) &mc_req, sizeof(mc_req))) < 0)
{
printf ("setsockopt() failed in IP_ADD_MEMBERSHIP %s\n", listen_ip_.c_str());
exit(1);
}
}
inline int ReadN (const unsigned int _len_, void * _dest_)
{
if (socket_file_descriptor_ != -1)
{
return recvfrom (socket_file_descriptor_, _dest_, _len_, 0, NULL, NULL);
}
return -1;
}
Просьба сообщить, пожалуйста, о любых улучшениях, которые могут быть сделаны.
Пара <224.0.25.46,13001> и <224.0.25.172,13001> предназначена для подачи питания и B-потока одного и того же потока пакетов, и в идеале требуется обработать пакет из того потока, который он набирает первым , Но инициализация двух экземпляров MulticastReceiverSocket и вызов ReadN() фактически обеспечивает 4 идентичных пакета для каждого экземпляра. –
С Linux 2.6.31 появилась новая функция, позволяющая отключить optioin IP_MULTICAST_ALL (см. Этот [ответ] (http: // stackoverflow.com/a/20919920/3102264)) – mpromonet