赞
踩
点对多点应用是指一个发送者,多个接收者的应用形式,这是最常见的多播应用形式。典型的应用包括:媒体广播、媒体推送、信息缓存、事件通知和状态监视等。
多点对点应用是指多个发送者,一个接收者的应用形式。通常是双向请求响应应用,任何一端(多点或点)都有可能发起请求。典型应用包括:资源查找、数据收集、网络竞拍、信息询问等。
多点对多点应用是指多个发送者和多个接收者的应用形式。通常,每个接收者可以接收多个发送者发送的数据,同时,每个发送者可以把数据发送给多个接收者。典型应用包括:多点会议、资源同步、并行处理、协同处理、远程学习、讨论组、分布式交互模拟(DIS)、多人游戏等。
IP 组播通信必须依赖于 IP 多播地址,在 IPv4 中它是一个 D 类 IP 地址,范围从 224.0.0.0 到 239.255.255.255,并被划分为局部链接多播地址、预留多播地址和管理权限多播地址三类:
1)局部链接多播地址范围在 224.0.0.0~224.0.0.255,这是为路由协议和其它用途保留的地址,路由器并不转发属于此范围的IP包;
2)预留多播地址为 224.0.1.0~238.255.255.255,可用于全球范围(如Internet)或网络协议;
3)管理权限多播地址为 239.0.0.0~239.255.255.255,可供组织内部使用,类似于私有 IP 地址,不能用于 Internet,可限制多播范围。
使用同一个 IP 多播地址接收多播数据包的所有主机构成了一个主机组,也称为多播组。一个多播组的成员是随时变动的,一台主机可以随时加入或离开多播组,多播组成员的数目和所在的地理位置也不受限制,一台主机也可以属于几个多播组。
这个我们可以这样理解,多播地址就类似于 QQ 群号,多播组相当于 QQ 群,一个个的主机就相当于群里面的成员。
设备驱动程序就必须接收所有多播数据帧,然后对它们进行过滤,这个过滤过程是网络驱动或IP层自动完成。(设备驱动程序会对多播数据进行过滤,将其发到相应的位置)
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int setsockopt(int sockfd, int level, int optname,
const void *optval, socklen_t optlen);
结构体原型
struct in_addr
{
in_addr_t s_addr;
}
struct ip_mreq
{
struct in_addr imn_multiaddr; // 多播组 IP,类似于 QQ 群号
struct in_addr imr_interface; // 将要添加到多播组的 IP,类似于QQ 成员号
};
tips:
多播组只能用UDP 或者原始套接字实现,不能用TCP
说明接收组播地址为224.0.0.88 或者 224.0.0.66 的信息,
//Udp_group_recv.c #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <unistd.h> int main(int argc,char *argv[]) { int socked=socket(AF_INET,SOCK_DGRAM,0); char group[16]="224.0.0.88"; char group_1[16]="224.0.0.66"; if(socked<0) { perror("socket failed!"); return 2; } struct sockaddr_in local_addr; memset(&local_addr,0,sizeof(local_addr)); local_addr.sin_family=AF_INET; local_addr.sin_addr.s_addr=htonl(INADDR_ANY); local_addr.sin_port=htons(8888); int ret=bind(socked,(struct sockaddr*)&local_addr,sizeof(local_addr)); if(ret<0) { perror("bind failed !"); return 3; } struct ip_mreq mreq; // 多播地址结构体 mreq.imr_multiaddr.s_addr=inet_addr(group); mreq.imr_interface.s_addr = htonl(INADDR_ANY); ret=setsockopt(socked,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)); if(ret<0) { perror("setsockopt failed !"); return 3; } else { printf("setsockopt success\n"); } mreq.imr_multiaddr.s_addr=inet_addr(group_1); ret=setsockopt(socked,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)); if(ret<0) { perror("setsockopt_1 failed !"); return 3; } else { printf("setsockopt_1 success\n"); } char buf[1024]; int length=0; struct sockaddr_in sender; int sender_len=sizeof(sender); while(1) { memset(buf, 0, sizeof(buf)); length=recvfrom(socked,buf,sizeof(buf),0,(struct sockaddr*)&sender,&sender_len); buf[length]='\0'; printf("%s %d : %s\n",inet_ntoa(sender.sin_addr),ntohs(sender.sin_port),buf); } setsockopt(socked, IPPROTO_IP, IP_DROP_MEMBERSHIP,&mreq, sizeof(mreq)); close(socked); return 0; }
//向组播地址为224.0.0.88的组发送信息
Udp_group_send.c #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <unistd.h> int main(int argc,char *argv[]) { char group_addr[16]="224.0.0.88"; int socked=socket(AF_INET,SOCK_DGRAM,0); if(socked<0) { perror("socket failed!"); return 2; } struct sockaddr_in remote_addr; memset(&remote_addr,0,sizeof(remote_addr)); remote_addr.sin_family=AF_INET; remote_addr.sin_addr.s_addr=inet_addr(group_addr); remote_addr.sin_port=htons(8888); char buf[1024]="This is a group udp"; int length=0; while(1) { memset(buf, 0, sizeof(buf)); length=sendto(socked,buf,strlen(buf),0,(struct sockaddr *)&remote_addr,sizeof(remote_addr)); printf("Send Message%s\n",buf); } close(socked); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。