Subject: Re: multicast
To: Robert Dobbs <banshee@gabriella.resort.com>
From: Francis Dupont <Francis.Dupont@inria.fr>
List: current-users
Date: 06/06/1995 13:25:54
In your previous mail you wrote:
Does anyone have some small sample code which uses multicasting?
=> I have a pair of small programs for multicast testing:
-------------------------------- in2multi.c --------------------------------
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
struct sockaddr_in msin;
main(argc, argv)
int argc;
char **argv;
{
unsigned char ttl;
int s, cc, ch;
char buf[1024];
u_long addr;
extern char *optarg;
extern int optind;
ttl = 0;
addr = htonl(INADDR_ANY);
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("socket");
exit(1);
}
while ((ch = getopt(argc, argv, "t:i:")) != -1)
switch(ch) {
case 't':
ttl = atoi(optarg);
break;
case 'i':
addr = htonl(inet_addr(optarg));
break;
}
argc -= optind;
argv += optind;
if (argc != 1) {
fprintf(stderr, "groupe manque\n");
exit(-1);
}
if (ttl > 0)
if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL,
&ttl, sizeof(ttl)) < 0) {
perror("setsockopt IP_MULTICAST_TTL");
return (0);
}
if (addr != htonl(INADDR_ANY))
if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF,
&addr, sizeof(addr)) < 0) {
perror("setsockopt IP_MULTICAST_IF");
return(0);
}
addr = inet_addr(*argv);
msin.sin_family = AF_INET;
msin.sin_addr.s_addr = htonl(addr);
msin.sin_port = htons(54321);
for (;;) {
cc = read(0, buf, 1024);
if (cc < 0) {
perror("read file");
return (cc);
} else if (cc > 0) {
if (sendto(s, buf, cc, 0,
(struct sockaddr *)&msin, sizeof(msin)) < 0)
perror("sendto");
fprintf(stderr, "-%d->\n", cc);
} else {
fprintf(stderr, ".\n", cc);
return (0);
}
}
}
-------------------------------- multi2out.c --------------------------------
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
struct sockaddr_in msin;
int s;
#define IPPORT 54321
Error(c, s)
char *c;
int s;
{
perror(c);
close(s);
exit(1);
}
void BrokenPipe(Signal, Code, SignalContextPtr)
int Signal, Code;
struct sigcontext *SignalContextPtr;
{
signal(SIGPIPE, BrokenPipe);
return;
}
main(argc, argv)
int argc;
char *argv[];
{
struct ip_mreq mreq;
int cc, ccb, ch;
char buf[10240];
int len;
int one = 1;
extern char *optarg;
extern int optind;
mreq.imr_interface.s_addr = INADDR_ANY;
signal(SIGPIPE, BrokenPipe);
while ((ch = getopt(argc, argv, "i:")) != -1)
switch(ch) {
case 'i':
mreq.imr_interface.s_addr = htonl(inet_addr(optarg));
break;
}
argc -= optind;
argv += optind;
if (argc != 1) {
fprintf(stderr, "groupe manque\n");
exit(-1);
}
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("socket");
exit(1);
}
(void) setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
msin.sin_family = AF_INET;
msin.sin_port = htons(IPPORT);
if (bind(s, (struct sockaddr *)&msin, sizeof(msin)) < 0) {
perror("bind");
exit(1);
}
mreq.imr_multiaddr.s_addr = htonl(inet_addr(*argv));
if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
&mreq, sizeof(mreq)) < 0) {
perror("setsockopt IP_ADD_MEMBERSHIP");
return (0);
}
for (;;) {
cc = read(s, buf, 10240);
if (cc < 0) {
perror("read socket");
return (cc);
} else if (cc > 0) {
ccb = write(1, buf, cc);
if (ccb != cc)
perror("write file");
fprintf(stderr, "<-%d-\n", cc);
} else {
fprintf(stderr, "..\n");
return (0);
}
}
}
-------------------------------- end --------------------------------
It is difficult to make them simpler... Please add your code
if you need more (for instance IP_MULTICAST_LOOP option).
Beware: multi2out can't detect the end of input.
Francis.Dupont@inria.fr