マルチキャスト送信とマルチキャスト受信のソースコード例
マルチキャストの原理はここでは紹介しませんが、私のブログにはマルチキャストの原理を紹介する詳細な文章があります.
ここでは小さな例を実現するだけですsend.cpp recv.cppファイル.
コンパイル後に2つのプロセスが生成され,1つは1つの送信を受信する.
Sender.cppファイルの内容は以下の通りです.
#include #include #include #include #include #include #include #include #include #define HELLO_PORT 12345 #define HELLO_GROUP "225.0.0.37"int 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, strlen(message), 0, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("sendto"); exit(1); } sleep(1); } }
Recver.cppファイルの内容は以下の通りです.
#include #include #include #include #include #include #include #include #include #define HELLO_PORT 12345 #define HELLO_GROUP "225.0.0.37"#define MSGBUFSIZE 256 int 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,(socklen_t*)&addrlen)) < 0) { perror("recvfrom"); exit(1); } puts(msgbuf); } return 0; }
Makefieファイルは次のとおりです.
CC = gcc CXX = g++ CFLAGS = -Wall -D_DEBUG -DDEBUG -g -O0 LDFLAGS = MODULE_INC = -I/usr/include MODULE_LIB = -L/usr/lib CFLAGS += $(MODULE_INC) LDFLAGS += $(MODULE_LIB) SENDOBJS = Sender.o RECVOBJS = Recver.o TARGET = Sender Recver all: $(TARGET) Sender: $(SENDOBJS) $(CXX) -o $@ $^ $(LDFLAGS) Recver: $(RECVOBJS) $(CXX) -o $@ $^ $(LDFLAGS) clean: rm -f *.o rm -f $(TARGET) rm -f http/*.o # make rule %.o : %.c $(CC) $(CFLAGS) -c $^ -o $@ %.o : %.cpp $(CC) $(CFLAGS) -c $^ -o $@
コンパイルメソッド
make
実行する
./Sender
./Recver
と入力します...
---------------------------------------------------------------------------------------------------
修正されたRecover.c、バイナリデータを受信し、入力パラメータを受信しますか?
ここでは小さな例を実現するだけですsend.cpp recv.cppファイル.
コンパイル後に2つのプロセスが生成され,1つは1つの送信を受信する.
Sender.cppファイルの内容は以下の通りです.
#include
Recver.cppファイルの内容は以下の通りです.
#include
Makefieファイルは次のとおりです.
CC = gcc CXX = g++ CFLAGS = -Wall -D_DEBUG -DDEBUG -g -O0 LDFLAGS = MODULE_INC = -I/usr/include MODULE_LIB = -L/usr/lib CFLAGS += $(MODULE_INC) LDFLAGS += $(MODULE_LIB) SENDOBJS = Sender.o RECVOBJS = Recver.o TARGET = Sender Recver all: $(TARGET) Sender: $(SENDOBJS) $(CXX) -o $@ $^ $(LDFLAGS) Recver: $(RECVOBJS) $(CXX) -o $@ $^ $(LDFLAGS) clean: rm -f *.o rm -f $(TARGET) rm -f http/*.o # make rule %.o : %.c $(CC) $(CFLAGS) -c $^ -o $@ %.o : %.cpp $(CC) $(CFLAGS) -c $^ -o $@
コンパイルメソッド
make
実行する
./Sender
./Recver
と入力します...
---------------------------------------------------------------------------------------------------
修正されたRecover.c、バイナリデータを受信し、入力パラメータを受信しますか?
#include <stdlib.h>
#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>
#include <unistd.h>
//#define HELLO_PORT 12345
//#define HELLO_GROUP "225.0.0.37"
#define MSGBUFSIZE 32*1024
int main(int argc, char *argv[])
{
if (argc != 4)
{
printf ("%s mulitAddr port bindIP
");
exit(129);
}
char* multiAddr = argv[1];
int port = atoi(argv[2]);
char* bindIP = argv[3];
printf ("%s:%d
", multiAddr, port);
printf ("bindIP = %s
", bindIP);
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 */
unsigned long nip = inet_addr (bindIP);
/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=INADDR_ANY; /* N.B.: differs from sender */
addr.sin_port=htons(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(multiAddr);
mreq.imr_interface.s_addr=inet_addr(bindIP);//htonl(INADDR_ANY);
if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0)
{
perror("setsockopt");
exit(1);
}
FILE* fp = fopen ("./xxxx.ts", "w+");
/* now just enter a read-print loop */
while (1)
{
addrlen=sizeof(addr);
if ((nbytes=recvfrom(fd, msgbuf, MSGBUFSIZE, 0, (struct sockaddr *) &addr,(socklen_t*)&addrlen)) < 0)
{
perror("recvfrom");
exit(1);
}
fwrite (msgbuf, 1, nbytes, fp);
printf ("write data %d bytes
", nbytes);
}
return 0;
}