I have done quite a bit of research on this but I can't find really any articles that's doing this exact setup I have. This is a pretty specific setup, so I am going to do my best to describe what I am doing and what I am trying to do.
I have a computer with 2 Ethernet ports (eth0 and eth1). Each one is receiving a different multicast broadcast at the same time. So 1 Multicast IP address and port is going to eth0 and another multicast IP address and port is going to eth1.
I am writing a program that is designed to listen to a given multicast IP address and port.
The goal is to be able to launch the program and listen to 1 of the multicast and at the same time launch a 2nd instance of the program that listens to the other multicast. The program itself is only designed to listen to 1 multicast at a time.
However I can not seem to have both programs running at the same time.
Using the "route" command I have been able to set up the routing table where I can receive 1 of the streams, but not the other. I can only ever get 1 stream going at a time, but not both.
eth0 is connected to: 10.10.20.50 -- multicast for this interface is 225.0.7.10 port 51007 eth1 is connected to: 192.168.20.21 -- multicast for this interface is 225.0.8.10 port 51008
If I do the route command, "route add default gw 10.10.20.50 eth0" I can receive the multicast on that address just fine
But as soon as I add "route add default gw 192.168.20.21 eth1" I can no longer receive the multicast on the 10.10.20.50 interface.
I do not get any errors with binding the sockets or setting the sockopts... the program just simply blocks on the recv call and never gets a message.
I have tried all sorts of combinations of the route command to support this, and I have done some various things in my connection code to fix this as well but with no luck. Here is my current connection code:
//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 ;
I have also tried using the ip_mreqn struct to specify the interface manually and used the setsockopt for SOL_BINDTODEVICE setup (eth0 or eth1) but ran into the same problem as before where I could only get it to connect if I had a particular route setup... and even then only 1 would receive and not the other.
To reiterate... I need to have 2 copies of this program running at the same time.. each one listening to it's own specified multicast address coming from specific interfaces.