1 | /* |
---|
2 | * listener.c -- joins a multicast group and echoes all data it receives from |
---|
3 | * the group to its stdout... |
---|
4 | * |
---|
5 | * Antony Courtney, 25/11/94 |
---|
6 | * Modified by: Frédéric Bastien (25/03/04) |
---|
7 | * to compile without warning and work correctly |
---|
8 | * |
---|
9 | * http://ntrg.cs.tcd.ie/undergrad/4ba2/multicast/antony/example.html |
---|
10 | */ |
---|
11 | |
---|
12 | #include <sys/types.h> |
---|
13 | #include <sys/socket.h> |
---|
14 | #include <netinet/in.h> |
---|
15 | #include <arpa/inet.h> |
---|
16 | #include <time.h> |
---|
17 | #include <string.h> |
---|
18 | #include <stdio.h> |
---|
19 | #include <stdlib.h> |
---|
20 | |
---|
21 | #include "mcast_params.h" |
---|
22 | |
---|
23 | #define HELLO_PORT MCAST_PORT |
---|
24 | #define HELLO_GROUP MCAST_ADDR |
---|
25 | |
---|
26 | #define MSGBUFSIZE 256 |
---|
27 | |
---|
28 | main(int argc, char *argv[]) |
---|
29 | { |
---|
30 | struct sockaddr_in addr; |
---|
31 | int fd, nbytes,addrlen; |
---|
32 | struct ip_mreq mreq; |
---|
33 | char msgbuf[MSGBUFSIZE]; |
---|
34 | |
---|
35 | u_int yes=1; /*** MODIFICATION TO ORIGINAL */ |
---|
36 | |
---|
37 | /* create what looks like an ordinary UDP socket */ |
---|
38 | if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) { |
---|
39 | perror("socket"); |
---|
40 | exit(1); |
---|
41 | } |
---|
42 | |
---|
43 | |
---|
44 | /**** MODIFICATION TO ORIGINAL */ |
---|
45 | /* allow multiple sockets to use the same PORT number */ |
---|
46 | if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0) { |
---|
47 | perror("Reusing ADDR failed"); |
---|
48 | exit(1); |
---|
49 | } |
---|
50 | /*** END OF MODIFICATION TO ORIGINAL */ |
---|
51 | |
---|
52 | /* set up destination address */ |
---|
53 | memset(&addr,0,sizeof(addr)); |
---|
54 | addr.sin_family=AF_INET; |
---|
55 | addr.sin_addr.s_addr=htonl(INADDR_ANY); /* N.B.: differs from sender */ |
---|
56 | addr.sin_port=htons(HELLO_PORT); |
---|
57 | |
---|
58 | /* bind to receive address */ |
---|
59 | if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) { |
---|
60 | perror("bind"); |
---|
61 | exit(1); |
---|
62 | } |
---|
63 | |
---|
64 | /* use setsockopt() to request that the kernel join a multicast group */ |
---|
65 | mreq.imr_multiaddr.s_addr=inet_addr(HELLO_GROUP); |
---|
66 | mreq.imr_interface.s_addr=htonl(INADDR_ANY); |
---|
67 | if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0) { |
---|
68 | perror("setsockopt"); |
---|
69 | exit(1); |
---|
70 | } |
---|
71 | |
---|
72 | /* now just enter a read-print loop */ |
---|
73 | while (1) { |
---|
74 | addrlen=sizeof(addr); |
---|
75 | if ((nbytes=recvfrom(fd,msgbuf,MSGBUFSIZE,0, |
---|
76 | (struct sockaddr *) &addr,&addrlen)) < 0) { |
---|
77 | perror("recvfrom"); |
---|
78 | exit(1); |
---|
79 | } |
---|
80 | puts(msgbuf); |
---|
81 | } |
---|
82 | } |
---|
83 | |
---|
84 | |
---|