linux многоадресное соединение не, почему? - PullRequest
0 голосов
/ 03 октября 2019

Мне нужно получать многоадресные данные из двух источников по одному Ethernet-соединению, 224.0.31.132, порт 14384 и 224.0.31.130, порт 14382. Сначала я попытался связаться с портом 14384, а затем соединить оба ip-адреса, но я получаю только данныеот 224.0.31.132. Если я связываюсь с 14382 и присоединяюсь к обоим, я получаю только данные из 224.0.31.130. Затем я попытался создать два сокета, привязать первый к 14384 и присоединиться к 224.0.31.132, затем привязать второй к 14382 и присоединиться к 224.0.31.130. Когда я делаю это, я получаю данные из 224.0.31.130, но не из 224.0.31.132, и ip maddr show показывает, что соединение с 224.0.31.132, очевидно, было удалено при настройке второго сокета.
Чтомне сделать, чтобы получать данные из этих двух источников на один порт eth?

Вот код для первого подхода:

/* Create a datagram socket on which to receive. */
int sd = socket(AF_INET, SOCK_DGRAM, 0);
if(sd < 0)
{
  perror("Opening datagram socket error");
  exit(1);
}
else
  cout<<"Opening datagram socket....OK."<<endl;

/* Enable SO_REUSEADDR to allow other */
/* applications to receive copies of the multicast datagrams. */
{
  int reuse = 1;
  if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
  {
    perror("Setting SO_REUSEADDR error");
    close(sd);
    exit(1);
  }
else
  cout<<"Setting SO_REUSEADDR...OK."<<endl;
}

/* Enable SO_REUSEPORT to allow multiple uses of receive port */
{
  int reuse = 1;
  if(setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, (char *)&reuse, sizeof(reuse)) < 0)
  {
    perror("Setting SO_REUSEPORT error");
    close(sd);
    exit(1);
  }
else
  cout<<"Setting SO_REUSEPORT...OK."<<endl;
}

/* Bind to the proper port number with the IP address */
/* specified as INADDR_ANY. */
struct sockaddr_in localSock;
memset((char *) &localSock, 0, sizeof(localSock));
localSock.sin_family = AF_INET;
localSock.sin_port = htons(14384);
localSock.sin_addr.s_addr = INADDR_ANY;
if(bind(sd, (struct sockaddr*)&localSock, sizeof(localSock)))
{
  perror("Binding datagram socket error");
  close(sd);
  exit(1);
}
else
  cout<<"Binding datagram socket...OK."<<endl;

/* Join the multicast groups on the local nic interface. */
struct ip_mreq group;
group.imr_interface.s_addr = inet_addr("0.0.0.0");
int ipcount = stoi(getSetup("mcstcount"));
while(ipcount>0)
{
  string which = "listenip" + to_string(ipcount);
  cout<<"listen to "<<getSetup(which.c_str())<<endl;
  group.imr_multiaddr.s_addr = inet_addr(getSetup(which.c_str()).c_str());
  ipcount--;
  if(setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0)
  {
    perror("Adding multicast group error");
    close(sd);
    exit(1);
  }
  else
    cout<<"Adding multicast group...OK."<<endl;
}

// process Mdp feed
while( !stop_cond  ) 
{
  /* Read from the socket. */
  const int DBUFSZ = 5000;
  uint8_t databuf[DBUFSZ];
  int datalen;
  datalen=read(sd, databuf, DBUFSZ);
  if(datalen < 0)
  {
    perror("Reading datagram message error");
    close(sd);
    exit(1);
  }

  //process data
}

Вот результат:

Opening datagram socket....OK.
Setting SO_REUSEADDR...OK.
Setting SO_REUSEPORT...OK.
Binding datagram socket...OK.
listen to 224.0.33.80
Adding multicast group...OK.
listen to 224.0.31.130
Adding multicast group...OK.
listen to 224.0.31.132
Adding multicast group...OK.

Но данные поступают только с 224.0.31.132.

1 Ответ

0 голосов
/ 03 октября 2019

В заключение нельзя использовать один сокет, так как есть несколько портов для приема. Вернулся, чтобы подойти к двум, используя несколько розеток. Работал, не уверен, что не так с первого раза.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...