#define GROUP "239.137.194.111"It will be also need to define a wearing of communication as that is usually done in traditional unicast mode.
#define PORT 55501The creation of the socket is done in the usual way, as indicated below:
/*
* Include files
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
/*
* sockets descriptors
*
* sdr: for receive
* sdw: for transmit
*/
int sdr, sdw;
/*
* sockets
*
* sock_r: for receive
* sock_w: for transmit
*/
struct sockaddr_in sock_r, sock_w;
/*
* sockets creation
*/
sdr = socket(PF_INET, SOCK_DGRAM, 0);
if (sdr < 0) {
perror("socket");
exit(1);
}
sdw = socket(PF_INET, SOCK_DGRAM, 0);
if (sdw < 0) {
perror("socket");
exit(1);
}
/*
* initialization of the reception socket
*/
memset(&sock_r, 0, sizeof(sock_r));
sock_r.sin_family = AF_INET;
sock_r.sin_port = htons(PORT);
#ifdef SOLARIS
sock_r.sin_addr.s_addr = htonl(INADDR_ANY);
#else
sock_r.sin_addr.s_addr = inet_addr(GROUP);
#endif
/*
* initialization of the socket of emission
*/
memset(&sock_w, 0, sizeof(sock_w));
sock_w.sin_family = AF_INET;
sock_w.sin_port = htons(PORT);
sock_w.sin_addr.s_addr = htonl(INADDR_ANY);
len_r = sizeof(sock_r);
len_w = sizeof(sock_w);
The function inet_addr("string") makes it
possible to convert the character string of 4 decimal bytes
representing address IP into a binary value coded on 32 bits network formated.
if (setsockopt(sdr, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, \
sizeof(struct ip_mreq)) < 0) {
perror("setsockopt - IP_ADD_MEMBERSHIP");
exit(1);
}
where imr is a structure of the type ip_mreq, defined in the file
/usr/include/netinet/in.h, which is described as follows:
struct ip_mreq {
struct in_addr imr_multiaddr; /* multicast group to join */
struct in_addr imr_interface; /* interface to join one */
}
/*
* allowance of the structure imr
*/
struct ip_mreq imr;
/*
* initialization of the structure imr
*/
imr.imr_multiaddr.s_addr = inet_addr(GROUP);
imr.imr_interface.s_addr = htonl(INADDR_ANY);
In reception mode it is also necessary to carry out an
operation bind() between the socket and its descriptor:
/*
* bind the socket
*/
if (bind(sdr, &sock_r, sizeof(sock_r)) < 0) {
perror("bind");
exit(1);
}
The reception itself of the data will be carried out by the
system call recvfrom() through the interface socket.
/*
* reception of datagrams
*/
while (1) {
cnt = recvfrom(sdr, buf, sizeof(buf), 0, &sock_r, &len_r);
if (cnt < 0) {
perror("recvfrom");
exit(1);
}
else if (cnt == 0) { /* end of transmission */
break;
}
printf("%s\n", buf); /* posting of the message */
}
The addresses ranging between 224.0.0.0 and 224.0.0.255 can be used locally on the sub-network but will never be forwarded by the routers for they are reserved for the protocols of routing.
To make tests it is advised to use a TTL of 1 and one address of the type "239.jj.mm.aa" where jj means the day, mm the month and aa the year.
The operation which makes it possible to fix the value of the TTL is the following one:
unsigned char ttl = 1;
setsockopt(sdw, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
The sending itself of the datas will be done by the system call
sendto() through the interface socket.
/*
* emission of the datagrams
*/
cnt = sendto(sdw, buf, strlen(buf), 0, &sock_w, len_w);
if (cnt < 0) {
perror("sendto");
exit(1);
}
setsockopt(sdr, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr, sizeof(imr));
int reuse = 1;
setsockopt(sdr, SOL_SOCKET, SO_REUSEADDR, (int *) &reuse, sizeof(reuse));
This system call must precede the system call bind().
unsigned char loop = 1; /* 0 = disable, 1 = enable * /
setsockopt(sdr, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
int vif = -1; /* -1 = enable normal multicast forwarding * /
setsockopt(sdr, IPPROTO_IP, IP_MULTICAST_VIF, &vif, sizeof(vif));
RMP defines 4 classes of objects:
©(Copyright) Philippe Dax -
1995,1996