Question to multicast concept with BSD Socket APIs

39 views Asked by At

I'm relatively new to topics such as socket programming and multicast messages. I'm trying to understand this concept better.

Let's say a PC is sending Multicast messages over address 224.0.0.0 on port 4010.

The receiver part has setup a UDP socket to listen for multicast messages.

My question is if I, for example, print out the IP address from the recvfrom() function, should this be the address multicast address 224.0.0.0, or the local IP address from the sender?

I have put my concrete question in the comments right on the part where I print the values. Also, is there anything wrong in the approach?

/*Sender IP is 11.12.13.14
Receiver local IP is 20.30.40.50*/


int sockUnicast;
int sockMulticast; /*For multicast*/

struct sockaddr_in local_addr;
struct sockaddr_in mcast_addr;

bool issockUnicastConnected = FALSE;
bool issockMulticastConnected = FALSE;

void myinit()
{
    sockUnicast = 0;
    sockMulticast = 0;
    
    /*Setup socket for unicast communicatin and bind it to any available port*/
    sockUnicast = socket(AF_INET,SOCK_DGRAM,0);
    
    if(sockUnicast >=0)
    {
        memset(&local_addr, 0, sizeof(local_addr));
        local_addr.sin_family = AF_INET;
        local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        local_addr.sin_port = htons(4000);
        
        if(bind(sockUnicast, (struct sockaddr*)&local_addr, sizeof(local_addr)) >=0)
        {
            issockUnicastConnected = TRUE;
        }
        
        /*Setup socket to listen on Multicast*/
        sockMulticast = socket(AF_INET,SOCK_DGRAM,0);
        
        memset(&mcast_addr, 0, sizeof(mcast_addr));
        mcast_addr.sin_family = AF_INET;
        mcast_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        mcast_addr.sin_port = htons(4010);
        
        if(sockMulticast>=0)
        {
            if((bind(sockMulticast, (struct sockaddr*)&mcast_addr, sizeof(mcast_addr)) >= 0))
            {
                struct ip_mreq mreq;
                mreq.imr_multiaddr.s_addr = inet_addr("224.0.0.0");
                mreq.imr_interface.s_addr = htonl(INADDR_ANY);
                
                if (setsockopt(sockMulticast, IPPROTO_IP, IP_ADD_MEMBERSHIP , (void*)&mreq, sizeof(mreq))>= 0)
                {
                    issockMulticastConnected = TRUE;
                }
            }
        }
        else
        {
            soc_close(sockMulticast);
        }
    else
    {
        soc_close(sockUnicast);
    }
}


void mymain()
{
   char buffer[2048];
   struct sockaddr_in src_addr;
   INT addrlen = sizeof(src_addr);
while(1)
{
    
     if(issockUnicastConnected)
     {
        ssize_t rec_len = recvfrom(sockUnicast,buffer,sizeof(buffer),0, (struct  sockaddr*)&src_addr, &addrlen);
        char ip_str[32];
        inet_ntop(AF_INET, &(src_addr.sin_addr), ip_str, 32);
        
        /*I'm sending a package from the sender (11.12.13.14) as Unicast to Address 20.30.40.50 and Port 4000*/
        /*Thats OK and I see it printed out*/
        
        print("Unicast IP address is:: %s\n", ip_str);   
        print("PORT is: %d\n", ntohs(src_addr.sin_port));
        
        if (rec_len > 0)
        {
          /*do something with data received on unicast*/;
        }
    }
    
     if(issockMulticastConnected)
     {
        ssize_t rec_len_multi = recvfrom(sockMulticast,buffer,sizeof(buffer),0, (struct  sockaddr*)&src_addr, &addrlen);
        char ip_str[32];
        inet_ntop(AF_INET, &(src_addr.sin_addr), ip_str, 32);
        
        /*Now If I send a a package as a multicast message with IP 224.0.0.0 and to PORT 4010 from the sender (11.12.13.14) shouldn't I see the multicast IP and Port printed out here? I get 0.0.0.0 */
        
        print("Multicast IP address is:: %s\n", ip_str);
        print("PORT is: %d\n", ntohs(src_addr.sin_port));

        if(rec_len_multi > 0)
        {
            /*do something with data received on multicast*/
        }
    }  
  }
}
2

There are 2 answers

0
Remy Lebeau On BEST ANSWER

recvfrom() tells you the IP and port where the datagram was sent from. This is the sender's local source address. 224.0.0.0:4010 is the destination address.

2
dbush On

The fifth argument to the recvfrom function will always be populated with the IP address of the sender, regardless of whether unicast or multicast was used.