I have broadly the following multicast socket code. It works fine. Now I need to join two multicast channels on the same machine like 224.10.13.18 - 55001 224.10.13.34 - 55001
and depending on which ip address it came from, I need to treat the message differently.
The question is to how to use create two sockets for multicast channels where the port values are same, such that each socket only returns read on data that is sent to that channel.
/* create socket to join multicast group on */
socket_file_descriptor_ = socket ( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
if ( socket_file_descriptor_ < 0 )
{ // fprintf ( stderr, "cannot open socket \n");
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 )
{ // fprintf ( stderr, "MulticastReceiverSocket setsockopt() SOL_SOCKET SO_REUSEADDR failed\n");
exit(1);
}
}
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)
{ // std::cerr << "setsockopt() failed in IP_ADD_MEMBERSHIP " << listen_ip_ << ": "<< listen_port_ << std::endl;
exit(1);
}
/* 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 )
{ // fprintf ( stderr, "%s cannot bind %s:%d \n", "MulticastReceiverSocket", listen_ip_.c_str(), listen_port_ ) ;
exit(1);
}
You only need one socket for this. If you set the
IP_PKTINFO
option on a call tosetsockopt
, you can userecvmsg
to get astruct in_pktinfo
, which will contain the destination IP address. Then you can choose how to process the packet based on that.Borrowing from https://stackoverflow.com/a/5309155/1687119 (error checking removed for brevity):