1.概念 单播是用于两个主机之间传送数据,广播是一个主机对局域网内的所有主机发送数据。而多播,又称为组播,它是对一组特定的主机通信。将网络上同一类型业务逻辑上分组,只和组内的成员通信,其它主机没有加入组则不能通信。与单播相同的是,组播允许在Internet上通信,而广播只是同一局域网内的主机通信。组播地址是特定的,D类地址用于组播,即244.0.0.0到239.255.255.255. 并划分为局部连接多播地址,预留多播地址和管理权限多播地址3类。 (1)局部多播地址 (224.0.0.-224.0.0.255)为路由协议和其它用途保留的地址,路由器不转发此范围的IP包 (2)预留多播地址 (224.0.1.0-238.255.255.255)可用于全球范围内或网络协议 (3)管理权限的多播 (239.0.0.0-239.255.255.255) 可供组织内使用,类型于私有IP,不用于Internet,可限制多播范围
2. 多播套接字设置 可用setsockopt或getsockopt设置或得到多播选项. 常用的多播选项如下所示: IP_MULTICAST_TTL 设置多播的TTL值 IP_MULTICAST_IF 获取或设置多播接口 IP_MULTICAST_LOOP 禁止多播数据回送到本地loop接口 IP_ADD_MEMBERSHIP 将指定的接口加入多播 IP_DROP_MEMBERSHIP 退出多播组 struct ip_mreq{ int ttl=255; (1)建立socket (2)设置TTL值 IP_MULTICAST_TTL (3)设置是否允许本地回环 IP_MULTICAST_LOOP (4)加入多播组 IP_ADD_MEMBERSHIP (5)发送数据 send (6)接收数据 recv (7)退出多播组 IP_DROP_MEMBERSHIP
注意: TCP协议也不能用于多播.
4. 多播实例 服务器端不停的向加入多播组的主机发送数据. 服务器: #include <sys/socket.h> #include <sys/socket.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <netinet/in.h> //多播的客户端程序 #define PORT 8888 #define MCAST "224.0.0.88" int main(int argc,char*argv[]){ int s; int ret; int size; int ttl=10;//如果转发的次数等于10,则不再转发 int loop=0; int times=0; char buffer[1024]; struct sockaddr_in localaddr,fromaddr;//多播地址结构 //建立套接字 s=socket(AF_INET,SOCK_DGRAM,0); if(s<0){ perror("socket error"); return -1; } //多播的地址结构 localaddr.sin_family=AF_INET; localaddr.sin_port=htons(PORT);//多播端口号 localaddr.sin_addr.s_addr=htonl(INADDR_ANY);//接收任意地址发送的数据 //绑定地址结构到套接字 ret=bind(s,(struct sockaddr*)&localaddr,sizeof(localaddr));//客户端需要绑定端口,用来接收服务器的数据,得指定接收端口,因为数据先从服务器发送过来的 if(ret<0){ perror("bind error"); return -1; } //设置多播的TTL值 if(setsockopt(s,IPPROTO_IP,IP_MULTICAST_TTL,&ttl,sizeof(ttl))<0){ perror("IP_MULTICAST_TTL"); return -1; } //设置数据是否发送到本地回环接口 if(setsockopt(s,IPPROTO_IP,IP_MULTICAST_LOOP,&loop,sizeof(loop))<0){ perror("IP_MULTICAST_LOOP"); return -1; } //客户端加入多播组 struct ip_mreq mreq; mreq.imr_multiaddr.s_addr=inet_addr(MCAST);//多播组的IP mreq.imr_interface.s_addr=htonl(INADDR_ANY);//本机的默认接口IP if(setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq))<0){ perror("IP_ADD_MEMBERSHIP"); return -1; } //循环接收多播组的消息,5次退出 for(times=0;times<20;times++){ int len=sizeof(fromaddr); memset(buffer,0,sizeof(buffer)); size=recvfrom(s,buffer,1024,0,(struct sockaddr*)&fromaddr,&len); if(size<0){ perror("recvfrom "); return -1; } printf("receive message:%s\n",buffer); printf("Port is:%d\n",fromaddr.sin_port); size=sendto(s,"OK",2,0,(struct sockaddr*)&fromaddr,sizeof(fromaddr));//向服务器发送数据,向服务器指定的IP与端口发送数据 } //离开多播组 ret=setsockopt(s,IPPROTO_IP,IP_DROP_MEMBERSHIP,&mreq,sizeof(mreq)); if(ret<0){ perror("IP_DROP_MEMBERSHIP"); return -1; } close(s); return 0; }
说明:设置主机的TTL值,是否允许本地回环,加入多播组,然后服务器向加入多播组的主机发送数据,主机接收数据,并响应服务器。
总结: 本文主要介绍了多播的概念,多播程序的设计流程,最后给了一个多播的实例.
|
|