组播中的setsockopt

来源:互联网 发布:西南证券交易软件下载 编辑:程序博客网 时间:2024/05/16 05:50

组播主机需要的环境
       如果要在一台主机上运行多播程序,这台主机支持IGMP协议。此协议用于加入一个多播组,离开一个多播组等而向路由器发送命令。现在的IGMP协议最高版本为v3(rfc3376),现在有很少数的UNIX实现了,WindowXp己实现。大部分主机,路由器实现的版本为v2(rfc2236),而v1版本(rfc1112)的运行是从v2中可以实现。V2与v1的区别就是把V1版本中的4位版本字段跟4位操作类型字段合并成了8位操作类型,在V1中不用使用的8位字段在V2中被称之为最大响应时间。用C写V2的IGMP结构即为:
struct igmp
{
    u_char igmp_type;
    u_char igmp_code;
    u_char igmp_cksum;
    struct in_addr igmp_addr;
};

组播需要的网络环境
       如果主机想获得多播报文,相邻的路由器也必须支持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);

原创粉丝点击