您好,欢迎访问三七文档
当前位置:首页 > 建筑/环境 > 设计及方案 > Linux网络编程之多播
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退出多播组structip_mreq{structin_addrimn_multicastaddr;//多播组地址structin_addrimr_interface;//加入的接口的IP地址}intttl=255;setsockopt(s,IPPROTO_IP,IP_MULTICAST_TTL,&ttl,sizeof(ttl));//设置跳数s-套接字描述符PROTO_IP-选项所在的协议层IP_MULTICAST_TTL-选项名&ttl-设置的内存缓冲区sizeof(ttl)-设置的内存缓冲区长度structin_addrin;setsockopt(s,IPPROTO_IP,IP_MUTLICAST_IF,&in,sizeof(in));//设置组播接口intyes=1;setsockopt(s,IPPROTO_IP,IP_MULTICAST_LOOP,&yes,sizeof(yes));//设置数据回送到本地回环接口structip_mreqaddreq;setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&req,sizeof(req));//加入组播组structip_mreqdropreq;setsockopt(s,IPPROTO_IP,IP_DROP_MEMBERSHIP,&dropreq,sizeof(dropreq));//离开组播组3.多播程序的设计流程(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.多播实例服务器端不停的向加入多播组的主机发送数据.服务器:#includesys/socket.h#includesys/types.h#includestring.h#includestdlib.h#includestdio.h#includearpa/inet.h/**广播与多播只支持UDP协议,因为TCP协议是端到端,这与广播与多播的理念相冲突广播是局域网中一个主机对所有主机的数据通信,而多播是一个主机对一组特定的主机进行通信.多播可以是因特网,而广播只能是局域网。多播常用于视频电话,网上会议等。setsockopt设置套接字选项可以设置多播的一些相关信息IP_MULTICAST_TTL//设置多播的跳数值IP_ADD_MEMBERSHIP//将主机的指定接口加入多播组,以后就从这个指定的接口发送与接收数据IP_DROP_MEMBERSHIP//主机退出多播组IP_MULTICAST_IF//获取默认的接口或设置多播接口IP_MULTICAST_LOOP//设置或禁止多播数据回送,即多播的数据是否回送到本地回环接口structip_mreq{structin_addrimn_multicastaddr;//多播组地址structin_addrimr_interface;//加入的接口的IP地址}例子:intttl=255;setsockopt(s,IPPROTO_IP,IP_MULTICAST_TTL,&ttl,sizeof(ttl));//设置跳数s-套接字描述符PROTO_IP-选项所在的协议层IP_MULTICAST_TTL-选项名&ttl-设置的内存缓冲区sizeof(ttl)-设置的内存缓冲区长度structin_addrin;setsockopt(s,IPPROTO_IP,IP_MUTLICAST_IF,&in,sizeof(in));//设置组播接口intyes=1;setsockopt(s,IPPROTO_IP,IP_MULTICAST_LOOP,&yes,sizeof(yes));//设置数据回送到本地回环接口structip_mreqaddreq;setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&req,sizeof(req));//加入组播组structip_mreqdropreq;setsockopt(s,IPPROTO_IP,IP_DROP_MEMBERSHIP,&dropreq,sizeof(dropreq));//离开组播组组播程序的设计流程:(1)建立socket(2)设置跳数TTL(3)设置是否允许本地回环(4)加入组播组(5)发送数据(6)接收数据(7)离开多播组(8)关闭套接字**///服务器实现向多播组发送数据#defineMCAST_PORT8888#defineMCAST_ADDR224.0.0.88intmain(intargc,char*argv[]){intret;ints;inti=1;structsockaddr_inMulti_addr;//多播地址structsockaddr_inclient_addr;s=socket(AF_INET,SOCK_DGRAM,0);//建立数据报套接字if(s0){perror(socketerror);return-1;}Multi_addr.sin_family=AF_INET;Multi_addr.sin_port=htons(MCAST_PORT);//多播端口Multi_addr.sin_addr.s_addr=inet_addr(MCAST_ADDR);//多播地址//向多播组发送数据charbuffer[1024];for(;;){memset(buffer,0,sizeof(buffer));sprintf(buffer,%d,i);intsize=sendto(s,buffer,strlen(buffer),0,(structsockaddr*)&Multi_addr,sizeof(Multi_addr));if(size0){perror(sendtoerror);}sleep(1);i++;memset(buffer,0,sizeof(buffer));intlen=sizeof(client_addr);size=recvfrom(s,buffer,1024,0,(structsockaddr*)&client_addr,&len);write(1,buffer,size);}close(s);}加入多播组的主机:#includesys/types.h#includesys/socket.h#includestring.h#includestdio.h#includestdlib.h#includenetinet/in.h//多播的客户端程序#definePORT8888#defineMCAST224.0.0.88intmain(intargc,char*argv[]){ints;intret;intsize;intttl=10;//如果转发的次数等于10,则不再转发intloop=0;inttimes=0;charbuffer[1024];structsockaddr_inlocaladdr,fromaddr;//多播地址结构//建立套接字s=socket(AF_INET,SOCK_DGRAM,0);if(s0){perror(socketerror);return-1;}//多播的地址结构localaddr.sin_family=AF_INET;localaddr.sin_port=htons(PORT);//多播端口号localaddr.sin_addr.s_addr=htonl(INADDR_ANY);//接收任意地址发送的数据//绑定地址结构到套接字ret=bind(s,(structsockaddr*)&localaddr,sizeof(localaddr));//客户端需要绑定端口,用来接收服务器的数据,得指定接收端口,因为数据先从服务器发送过来的if(ret0){perror(binderror);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;}//客户端加入多播组structip_mreqmreq;mreq.imr_multiaddr.s_addr=inet_addr(MCAST);//多播组的IPmreq.imr_interface.s_addr=htonl(INADDR_ANY);//本机的默认接口IPif(setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq))0){perror(IP_ADD_MEMBERSHIP);return-1;}//循环接收多播组的消息,5次退出for(times=0;times20;times++){intlen=sizeof(fromaddr);memset(buffer,0,sizeof(buffer));size=recvfrom(s,buffer,1024,0,(structsockaddr*)&fromaddr,&len);if(size0){perror(recvfrom);return-1;}printf(receivemessage:%s\n,buffer);printf(Portis:%d\n,fromaddr.sin_port);size=sendto(s,OK,2,0,(structsockaddr*)&fromaddr,sizeof(fromaddr));//向服务器发送数据,向服务器指定的IP与端口发送数据}//离开多播组ret=setsockopt(s,IPPROTO_IP,IP_DROP_MEMBERSHIP,&mreq,sizeof(mreq));if(ret0){perror(IP_DROP_MEMBERSHIP);return-1;}close(s);return0;}说明:设置主机的TTL值,是否允许本地回环,加入多播组,然后服务器向加入多播组的主机发
本文标题:Linux网络编程之多播
链接地址:https://www.777doc.com/doc-2885010 .html