我正在努力了解IP多播。特别是,我想禁止将数据包循环回多播组。
我只是将这些代码放在一起,以示例我所看到的。
/*
example.c
*/
#include <sys/types.h>
#include <net/if.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#define EXAMPLE_PORT 6000
#define EXAMPLE_GROUP "224.0.0.1"
const long MYSENDER = 0; // send thread ID
const long MYRECVR = 1; // recv thread ID
int status;
int sock;
void *sender(void *threadid);
void *receiver(void *threadid);
main(int argc) {
pthread_t threads[2];
struct sockaddr_in addr;
/* Set up socket */
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == -1) {
perror("socket");
exit(1);
}
status = pthread_create(&threads[MYRECVR], NULL, receiver, (void *) MYRECVR); // Start the server thread and check for error
if (status) {
fprintf(stderr, "Error: pthread_create(receiver) returned %d\n", status);
exit(-1);
}
status = pthread_create(&threads[MYSENDER], NULL, sender, (void *) MYSENDER); // Start the client thread and check for error
if (status) {
fprintf(stderr, "Error: pthread_create(sender) returned %d\n", status);
exit(-1);
}
pthread_join(threads[MYRECVR], NULL); // main() will wait for the server thread to complete
pthread_join(threads[MYSENDER], NULL); // main() will wait for the client thread to complete
}
void *sender(void *threadid) {
int c;
char message[50];
struct sockaddr_in addr;
int addrlen, cnt;
memset((char *) &addr, 0, sizeof (addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_addr.s_addr = inet_addr(EXAMPLE_GROUP);
addr.sin_port = htons(EXAMPLE_PORT);
addrlen = sizeof (addr);
fprintf(stderr, "Starting sender thread!\n");
/* Send */
while (1) {
time_t t = time(0);
sprintf(message, "time is %-24.24s", ctime(&t));
printf("sending: %s\n", message);
cnt = sendto(sock, message, sizeof (message), 0,
(struct sockaddr *) &addr, addrlen);
if (cnt < 0) {
perror("sendto");
exit(1);
}
sleep(5);
}
return 0;
}
void *receiver(void *threadid) {
int opt = 1;
char message[50];
struct sockaddr_in addr;
int addrlen, cnt;
struct ip_mreq mreq;
fprintf(stderr, "Starting receiver thread!\n");
memset((char *) &addr, 0, sizeof (addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(EXAMPLE_PORT);
addrlen = sizeof (addr);
/* Receive */
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt));
if (bind(sock, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
perror("bind");
exit(1);
}
mreq.imr_multiaddr.s_addr = inet_addr(EXAMPLE_GROUP);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
&mreq, sizeof (mreq)) < 0) {
perror("setsockopt mreq");
exit(1);
}
while (1) {
cnt = recvfrom(sock, message, sizeof (message), 0,
(struct sockaddr *) &addr, &addrlen);
if (cnt < 0) {
perror("recvfrom");
exit(1);
} else if (cnt == 0) {
break;
}
printf("%s: message = \"%s\"\n", inet_ntoa(addr.sin_addr), message);
}
return 0;
}
运行正常并产生以下输出......
picozed@ubuntu:/tmp$ ./test
Starting receiver thread!
Starting sender thread!
sending: time is Wed Aug 16 19:23:29 2017
10.249.27.51: message = "time is Wed Aug 16 19:23:29 2017"
sending: time is Wed Aug 16 19:23:34 2017
10.249.27.51: message = "time is Wed Aug 16 19:23:34 2017"
^C
picozed@ubuntu:/tmp$
但是,我想阻止这些消息被重新载入......
答案 0 :(得分:1)
默认情况下,大多数操作系统会将传出的多播流量循环回本地计算机。如果要禁用此行为,则需要将IP_MULTICAST_LOOP
套接字选项设置为0。
int opt=0;
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &opt, sizeof (opt)) < 0) {
perror("setsockopt");
exit(1);
}