Search in shivacherukuri.tech@blogger.com

Wednesday, January 19, 2011

Multicast datagrams example

Sending Multicast Datagrams

Sending a multicast datagram is easy: The sender simply specifies a multicast address as the destination of an ordinary sendto(2) system call.


Receiving Multicast Datagrams

To receive multicast packets, an application must first request that the host join a particular multicast group. This is done using another call to setsockopt(2):

	struct ip_mreq mreq;

setsockopt(sock,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));

The definition of struct ip_mreq is as follows:

	struct ip_mreq {
struct in_addr imr_multiaddr; /* multicast group to join */
struct in_addr imr_interface; /* interface to join on */
}

For now, imr_interface can be safely set to INADDR_ANY to join on the default multicast network interface.

In addition to the host part of an IP multicast address, there is also a port number, as in TCP or UDP sockets. This port number information is used by the kernel to decide which port on the local machine to route packets to. However, unlike in TCP or UDP, there can be many sockets which receive IP multicast packets off a single local port. Binding the socket to a local port is done with bind(2), and is done in the same manner as binding to a UDP address.

After the bind(2) has been performed and we have used setsockopt(2) to join a multicast group, we are ready to receive. An ordinary recvfrom(2) call may be used to read datagrams off of the receive socket.


An Example of Multicast Programming: "Hello, World!"

Here is an example which illustrates all the facilities described here for using multicast. It consists of two programs: sender and listener. The listener program simply echoes everything it receives to its standard out, and the sender multicasts "hello, world!" to everyone else in the multicast group.



=====

Multicast Example Programs


Sender Program

/*
* sender.c -- multicasts "hello, world!" to a multicast group once a second
*
* Antony Courtney, 25/11/94
*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>


#define HELLO_PORT 12345
#define HELLO_GROUP "225.0.0.37"

main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd, cnt;
struct ip_mreq mreq;
char *message="Hello, World!";

/* create what looks like an ordinary UDP socket */
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
perror("socket");
exit(1);
}

/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr(HELLO_GROUP);
addr.sin_port=htons(HELLO_PORT);

/* now just sendto() our destination! */
while (1) {
if (sendto(fd,message,sizeof(message),0,(struct sockaddr *) &addr,
sizeof(addr)) < 0) {
perror("sendto");
exit(1);
}
sleep(1);
}
}

Listener Program

/*
* listener.c -- joins a multicast group and echoes all data it receives from
* the group to its stdout...
*
* Antony Courtney, 25/11/94
* Modified by: Frédéric Bastien (25/03/04)
* to compile without warning and work correctly
*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>


#define HELLO_PORT 12345
#define HELLO_GROUP "225.0.0.37"
#define MSGBUFSIZE 256

main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd, nbytes,addrlen;
struct ip_mreq mreq;
char msgbuf[MSGBUFSIZE];

u_int yes=1; /*** MODIFICATION TO ORIGINAL */

/* create what looks like an ordinary UDP socket */
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
perror("socket");
exit(1);
}


/**** MODIFICATION TO ORIGINAL */
/* allow multiple sockets to use the same PORT number */
if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0) {
perror("Reusing ADDR failed");
exit(1);
}
/*** END OF MODIFICATION TO ORIGINAL */

/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=htonl(INADDR_ANY); /* N.B.: differs from sender */
addr.sin_port=htons(HELLO_PORT);

/* bind to receive address */
if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) {
perror("bind");
exit(1);
}

/* use setsockopt() to request that the kernel join a multicast group */
mreq.imr_multiaddr.s_addr=inet_addr(HELLO_GROUP);
mreq.imr_interface.s_addr=htonl(INADDR_ANY);
if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0) {
perror("setsockopt");
exit(1);
}

/* now just enter a read-print loop */
while (1) {
addrlen=sizeof(addr);
if ((nbytes=recvfrom(fd,msgbuf,MSGBUFSIZE,0,
(struct sockaddr *) &addr,&addrlen)) < 0) {
perror("recvfrom");
exit(1);
}
puts(message);
}
}

No comments:

Post a Comment