组播

组播需要的网络环境
如果主机想获得多播报文,相邻的路由器也必须支持IGMP,如果想获得Internet上的多播报文,主机到Server的这个路径中所遇到的路由器必须全部支持IGMP,路由器还必须支持源发现协议,如MSDP,PIM_DM,PIM_SM等。

组播的等级
Level 0    不支持IP多播
Level 1    只支持向多播组发送数据而不能接收多播组的数据
Level 2    IP多播全支持

    对这三个等级的理解应该从SOCKET上。建立了一个SOCKET以后可以对它进行设置,看它需求什么。一般现在存在的网络程序就就是Level0了,因为它们不支持多播,如用于连接web服务器获取网页内容的那个SOCKET就应该属于Level0。
    一个演唱会现场网络直播,由于采用了多播,服务器要向一个多播组发送报文,因为他不需要获取接收者的报文,所以可以建立一个SOCKET只向特定的多播组发送数据就可以了,这个SOCKET应该就是Level 1。
      一个网络会议的例子,由于会议是有多个人参加的,每个人都需要接收其它人的报文,所以建立了一个SOCKET,首先把这个SOCKET加入到一个多播组,使其能接收多播组的数据,然后它也可以用这个SOCKET向自己加入的多播组发送自己的状态。这个SOCKET就应该是Level 2了。

组播编程相关的socket结构和函数
int setsockopt(SOCKET s, int level, int optname, const char FAR * optval, int optlen);
int getsockopt(SOCKET s, int level, int optname, char FAR * optval, int FAR * optlen);

level必须为IPPROTO_IP。不要问为什么。这两个函数在组播干什么呢?获取系统对组播的设置(如TTL),加入一个多播组、离开一个多播组就用setsockopt 。optname就是在组播起到最主要作用的一个字段,与组播相关的可取值如下:

可取值                                  setsockopt     getsockopt
IP_MULTICAST_LOOP       支持               支持
IP_MULTICAST_TTL           支持               支持
IP_MULTICAST_IF              支持               支持
IP_ADD_MEMBERSHIP      支持               不支持
IP_DROP_MEMBERSHIP   支持               不支持

1.         IP_MULTICAST_LOOP
当接收者加入到一个多播组以后,再向这个多播组发送数据,这个字段的设置是否允许再返回到本身。

2.         IP_MULTICAST_TTL
默认情况下,多播报文的TTL被设置成了1,也就是说到这个报文在网络传送的时候,它只能在自己所在的网络传送,当要向外发送的时候,路由器把TTL减1以后变成了0,这个报文就已经被Discard了。例:
    char ttl;
    ttl = 2;
    setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char*)ttl, sizeof(ttl));

3.         IP_MULTICAST_IF
发送多播报文时用的本地接口,默认情况下被设置成了本地接口的第一个地址。
4.         IP_ADD_MEMBERSHIP
这个option和下面的option是实现多播必不可少的,它用于加入一个多播组,例:
    struct ip_mreq ipmr;
    ipmr.imr_interface.s_addr = htonl(INADDR_ANY);
    ipmr.imr_multiaddr.s_addr = inet_addr("234.5.6.7");
    setsockopt(s, IPPROTO_IP, IP_ADDR_MEMBERSHIP, (char*)&ipmr, sizeof(ipmr));
5.         IP_DROP_MEMBERSHIP
用于离开一个多播组,使用方法同IP_ADDR_MEMBERSHIP。
    struct ip_mreq ipmr;
    int             len;
   setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char*)&ipmr, &len);


http://www.cnblogs.com/hateislove214/archive/2010/11/05/1869868.html

http://www.cnblogs.com/hateislove214/archive/2010/11/05/1869883.html

 

m_sendAddr.sin_family = AF_INET;
m_sendAddr.sin_port = htons( m_send_port );
inet_pton(AF_INET, m_send_ip, &m_sendAddr.sin_addr.s_addr);
m_udpsocket = socket( AF_INET , SOCK_DGRAM , IPPROTO_UDP);
bind(m_udpsocket, (SA*)&m_sendAddr, sizeof(m_sendAddr) );
setsockopt(m_udpsocket, IPPROTO_IP, IP_MULTICAST_IF, (char*)&m_sendAddr.sin_addr, sizeof(m_sendAddr.sin_addr));
//把地址改为组地址, 以便后面向组内发送
m_sendAddr.sin_addr.s_addr = inet_addr( (char*)m_send_ip );
struct ip_mreq mreq;
memset(&mreq, 0, sizeof(struct ip_mreq));
/* 设置组地址 */
mreq.imr_multiaddr.s_addr = inet_addr(m_send_ip);
/* 设置发送组播消息的源主机的地址信息 */
mreq.imr_interface.s_addr = htons(INADDR_ANY);
setsockopt(m_udpsocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(struct ip_mreq));
int mc_loop = 0;
setsockopt(m_udpsocket, IPPROTO_IP, IP_MULTICAST_LOOP, (char*)&mc_loop, sizeof(int) );
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值