2

OS: CentOS 5.5
言語: C++

私はこれについてかなりの調査を行いましたが、私が持っているこの正確な設定を行っている記事を実際に見つけることができません. これは非常に具体的な設定なので、私が何をしているのか、何をしようとしているのかを説明するために最善を尽くします.

2 つのイーサネット ポート (eth0 と eth1) を備えたコンピューターを使用しています。それぞれが同時に異なるマルチキャスト ブロードキャストを受信して​​います。つまり、1 つのマルチキャスト IP アドレスとポートが eth0 に送信され、別のマルチキャスト IP アドレスとポートが eth1 に送信されます。

特定のマルチキャスト IP アドレスとポートをリッスンするように設計されたプログラムを作成しています。

目標は、プログラムを起動してマルチキャストの 1 つをリッスンし、同時に他のマルチキャストをリッスンするプログラムの 2 番目のインスタンスを起動できるようにすることです。プログラム自体は、一度に 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 構造体を使用してインターフェイスを手動で指定しようとしましたが、SOL_BINDTODEVICE セットアップ (eth0 または eth1) に setsockopt を使用しましたが、以前と同じ問題に遭遇し、特定のルートがセットアップされている場合にのみ接続できました.. . そしてそれでも、一方だけが受信し、他方は受信しません。

繰り返しますが、このプログラムの 2 つのコピーを同時に実行する必要があります。

4

2 に答える 2

0

2 つの異なるルートをセットアップする必要があるため、異なるグループが特定のインターフェイスにルーティングされる (したがってリッスンされる) ようになります。

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 の本のソース コードを入手してください。解凍さunpv13e/libれたアーカイブのディレクトリを調べて、mcast_join.cファイルを読み取ります。

于 2012-06-27T21:08:16.027 に答える