多个接口上的多个组播

时间:2012-06-27 20:54:29

标签: c++ linux networking multicast

操作系统:CentOS 5.5
语言:C ++

我已经对此进行了相当多的研究,但我找不到任何正在进行这种确切设置的文章。这是一个非常具体的设置,所以我将尽我所能来描述我在做什么以及我想做什么。

我有一台带有2个以太网端口(eth0和eth1)的计算机。每个人同时接收不同的多播广播。因此,1个多播IP地址和端口将转至eth0,另一个多播IP地址和端口将转至eth1。

我正在编写一个旨在侦听给定多播IP地址和端口的程序。

目标是能够启动程序并监听多播中的一个,同时启动侦听其他多播的程序的第二个实例。该程序本身仅用于一次侦听1个多播。

但是我似乎无法让两个程序同时运行。

使用“route”命令我已经能够设置路由表,我可以在其中接收1个流,但不能接收另一个流。我一次只能获得1个流,但不能同时获得两个流。

eth0连接到:10.10.20.50 - 此接口的多播是225.0.7.10端口51007 eth1连接到:192.168.20.21 - 此接口的多播为225.0.8.10端口51008

如果我执行route命令,“route add default gw 1​​0.10.20.50 eth0”我可以在该地址上收到多播

但是一旦我添加“route add default gw 1​​92.168.20.21 eth1”,我就无法再在10.10.20.50界面上收到多播。

我没有遇到任何绑定套接字或设置sockopts的错误......程序只是简单地阻止了recv调用并且永远不会收到消息。

我已经尝试过各种各样的route命令组合来支持这个,我在连接代码中做了一些不同的事情来解决这个问题,但没有运气。这是我目前的连接代码:

  //Create the UDP socket, check to make sure it was created successfully
  cout << "Initializing Connection..." << endl ;
  m_socket = socket ( AF_INET , SOCK_DGRAM , IPPROTO_UDP ) ;

  if( m_socket == -1 )
  {
    cout << "ERROR CREATING SOCKET: " << strerror(errno) << endl ;
    return false ;
  }

  cout << "Socket Created" << endl;

  //Setup socket binding information
  sockaddr_in addr ;
  bzero  ( ( char* ) &addr , sizeof ( addr ) ) ;
  addr . sin_family       = AF_INET ;
  addr . sin_addr.s_addr  = inet_addr(interface_addr) ; //10.10.20.50 or 192.168.20.21
  addr . sin_port         = htons ( port ) ;            //51007 or 51008

  //bind the socket, check for errors
  int result = bind ( m_socket , ( struct sockaddr* ) &addr , sizeof ( addr ) ) ;

  if ( result == -1 )
  {
    cout << "ERROR BINDING PORT: " << strerror ( errno ) << endl;
    shutdown ( m_socket , SHUT_RDWR ) ;
    return false ;
  }

  cout << "Socket Bound" << endl;

  //subscribe to the supplied IP address and port to listen on
  in_addr host_addr ;
  inet_pton ( AF_INET , ip_addrs . c_str () , & ( host_addr ) ) ;

  struct ip_mreq mreq;
  mreq . imr_multiaddr = host_addr ;       // multicast address 225.0.7.10 or 225.0.8.10
  mreq . imr_interface = addr . sin_addr ; //the 10.10.20.50 or 192.168.20.21 specified above

  result = setsockopt ( m_socket , IPPROTO_IP , IP_ADD_MEMBERSHIP, &mreq , sizeof(mreq) ) ;

  if ( result == -1 )
  {
    cout << "ERROR SETTING SOCKOPT SUBSCRIPTION: " << strerror(errno) << endl ;
    printSocketError();
    shutdown ( m_socket , SHUT_RDWR ) ;
    return false ;
  }

  /*
   * Read from the socket to get the initial bit of information we need so the
   * buffers can get allocated correctly, and the width and height of the application
   * can be defined.
   */
  cout << "Attempting to read from the socket..." << endl;
  MyPacket pckt ;
  recv ( m_socket , &pckt , sizeof ( pckt ) , MSG_PEEK ) ;

  cout << "Data Received... processing" << endl ;

我也尝试使用ip_mreqn结构手动指定接口并使用setsockopt进行SOL_BINDTODEVICE设置(eth0或eth1),但遇到了与之前相同的问题,如果我有特定的路由,我只能连接它设置......即使这样,只有1个会接收而不会接收另一个。

重申......我需要同时运行此程序的2个副本..每个程序都会监听来自特定接口的指定多播地址。

2 个答案:

答案 0 :(得分:0)

您需要设置两个不同的路由,因此不同的组路由到(并因此监听)给定的接口:

root:~# route add -net 225.0.7.10 netmask 255.255.255.255 dev eth0
root:~# route add -net 225.0.8.10 netmask 255.255.255.255 dev eth1

然后,当您的程序正在运行时,您应该能够看到在netstat -ng的哪个界面上收听了哪些组。

编辑0:

编辑1:

获取我提到的UNP书籍的源代码,here。查看解压缩归档中的unpv13e/lib目录,阅读mcast_join.c文件。

答案 1 :(得分:0)

而是这样做 - 1.创建一个类。 2.具有在该类中创建和绑定IP和端口的功能。 3.使用该类Object,从main函数调用该函数两次。

要验证结果,您可以使用命令netstat -g,它将显示与您的多播IP相对应的两个实例。

如果你想要我,我可以编码,但首先要自己尝试。