/* NAME: multicasr receiver SYNOPSIS: McastRcv DESCRIPTION: The program creates a datagram socket and joins a multicast group. It prints on the standard output all received message. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "packetReg.h" int main( int argc, char * argv[] ) { int s; struct sockaddr_in mc_group; struct sockaddr_in from; int fromlen; int length; Packet pkt; int rc, n; struct ip_mreq mreq; /* multicast group info structure */ /* linux */ unsigned long int mcGroup; /* Solaris in_addr_t mcGroup; */ int reuse; char loop, ttl; fd_set readfds, readfdsCopy; if (argc != 4) { fprintf(stderr, "Usage : %s \n",argv[0]); exit(0); } s = socket (PF_INET,SOCK_DGRAM,0); /* Set socket to receive datagrams */ reuse=1; if ( setsockopt(s ,SOL_SOCKET,SO_REUSEADDR, (char *) &reuse,sizeof(reuse)) == -1 ){ printf("error in setsockopt,SO_REUSEPORT \n"); exit(-1); } mc_group.sin_family = AF_INET; mc_group.sin_addr.s_addr = INADDR_ANY; mc_group.sin_port = htons(atoi(argv[3])); if (bind( s, (struct sockaddr *)&mc_group, sizeof(mc_group)) < 0) { fprintf(stderr, "Can't bind ....\n"); exit (-1); } /* Join Multicast Group */ if( (mcGroup = inet_addr(argv[2]))== -1) printf("error in inet_addr\n"); mreq.imr_multiaddr.s_addr = mcGroup; mreq.imr_interface.s_addr = INADDR_ANY; if ( setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *) &mreq, sizeof(mreq)) == -1 ) { printf("error in joining group \n"); exit(-1); } /* Set socket to send datagrams */ mc_group.sin_addr.s_addr= mcGroup; loop = 1; if( setsockopt(s, IPPROTO_IP,IP_MULTICAST_LOOP,(char *) &loop, sizeof(u_char)) == -1 ) { printf("error in setting loopback\n"); } ttl = 5; if( setsockopt(s ,IPPROTO_IP,IP_MULTICAST_TTL,(char *) &ttl, sizeof(u_char)) == -1 ) { printf("error in setting loopback value\n"); } FD_ZERO(&readfdsCopy); FD_SET(s,&readfdsCopy); FD_SET(0,&readfdsCopy); for(;;){ memcpy(&readfds, &readfdsCopy, sizeof(fd_set)); n = select(FD_SETSIZE, &readfds, (fd_set *) 0, (fd_set *) 0, NULL); if (n > 0) { if (FD_ISSET(s, &readfds)) { fromlen = sizeof(from); if ((rc=recvfrom(s, (char *)&pkt, sizeof(pkt), 0, (struct sockaddr *)&from, &fromlen)) < 0) perror("receiving datagram message"); if (rc > 0){ printf("From %s:%d, %d bytes received\n", inet_ntoa(from.sin_addr), ntohs(from.sin_port), pkt.length); printf("%s wrote : %s \n", pkt.name, pkt.msg); if (strncmp(pkt.msg, "STOP", 4)== 0) break; } } if (FD_ISSET(0, &readfds)) { rc=read(0,pkt.msg, BUFSIZE); if (rc == 0) break; strcpy(pkt.name, argv[1]); pkt.msg[rc-1]='\0'; pkt.length = sizeof(pkt)-BUFSIZE+rc; printf("Sending %d bytes \"%s\"\n", pkt.length, pkt.msg); if (sendto(s, (char *)&pkt, pkt.length, 0, (struct sockaddr*)&mc_group, sizeof(mc_group)) <0 ) perror("sending datagram message"); } } } /* Leave multicast group */ mreq.imr_multiaddr.s_addr = mcGroup; mreq.imr_interface.s_addr = INADDR_ANY; if( setsockopt(s,IPPROTO_IP,IP_DROP_MEMBERSHIP, (char *) &mreq,sizeof(mreq)) == -1 ){ printf("error in leaving group \n"); exit(-1); } }