在一周左右的时间里,我一直在研究从单一来源向多个客户端发送数据报的方法,并发现IP支持224.0.0.0
和234.255.255.255
范围内的多播。我已经阅读了一些描述该技术的文档,但是我找不到任何有助于我理解如何使用它们的文档。
根据我收集的信息,程序似乎要求操作系统内核加入非关联的组播组,然后开始通过UDP将数据通过UDP发送到组播地址。其他所有内容都由WAN处理,而不需要在发送到的地址上进行任何物理处理。
这一思路已被我所读过的内容模糊地支持,但尚未得到证实。这个想法是否正确?如果有问题会有什么问题?
答案 0 :(得分:1)
这基本上是正确的。
在接收方,首先打开一个侦听特定端口的套接字。然后,您在给定的网络接口上加入多播地址。这样做会导致操作系统向网络发送IGMP消息,通知正在加入组的路由器。
在发件人方面,打开套接字,然后为多播配置传出网络接口。完成后,您可以将数据包发送到任何多播地址。
以下是C中的示例发件人:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <strings.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
struct sockaddr_in sin;
struct in_addr out_addr;
char mes[255], ttl;
int sock;
printf("Enter message: ");
fgets(mes, sizeof(mes), stdin);
bzero(&sin,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=inet_addr(argv[1]);
sin.sin_port=htons(atoi(argv[2]));
if ((sock=socket(AF_INET,SOCK_DGRAM,0))==-1) {
perror("Error creating socket");
exit(1);
}
out_addr.s_addr=inet_addr(argv[3]);
if (setsockopt(sock,IPPROTO_IP,IP_MULTICAST_IF,(char *)&out_addr,sizeof(out_addr))== -1) {
perror("Error setting outgoing interface");
close(sock);
exit(1);
}
if (sendto(sock,mes,strlen(mes),0,(struct sockaddr *)&sin,sizeof(sin))==-1) {
close(sock);
perror("Send error");
}
close(sock);
}
这是C中的示例接收器:
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int addr_len;
struct sockaddr_in sin,sin_recv;
struct ip_mreq multi;
char mes[255];
int sock;
bzero(&sin,sizeof(sin));
multi.imr_multiaddr.s_addr=inet_addr(argv[1]);
multi.imr_interface.s_addr=inet_addr(argv[2]);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(atoi(argv[3]));
if ((sock=socket(AF_INET,SOCK_DGRAM,0))==-1) {
perror("Error creating socket");
exit(1);
}
if (setsockopt(sock,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *)&multi,sizeof(multi))== -1) {
perror("Error joining multicast group");
close(sock);
exit(1);
}
if (bind(sock,(struct sockaddr *)&sin,sizeof(sin))==-1) {
perror("Error binding socket");
close(sock);
exit(1);
}
while (1) {
bzero(mes,sizeof(mes));
bzero(&sin_recv,sizeof(sin_recv));
addr_len=sizeof(sin_recv);
printf("Waiting for packet...\n");
if (recvfrom(sock,mes,sizeof(mes),0,(struct sockaddr *)&sin_recv,&addr_len)==-1) {
perror("error recving socket");
close(sock);
exit(1);
}
printf("Got packet\n");
printf("Origin: %s port %d\n",inet_ntoa(sin_recv.sin_addr),sin_recv.sin_port);
printf("Message: %s\n",mes);
}
}