现在的位置: 首页 > 综合 > 正文

multicast(一) (转自network programming for microsoft windows, second edition.)

2012年08月02日 ⁄ 综合 ⁄ 共 5822字 ⁄ 字号 评论关闭

 

看完这个就知道IGMPV3怎么实现了 。。。
Multicasting with Setsockopt

Originally, the only way to join or leave a multicast group was
via the setsockopt API. Winsock 2 introduces a
protocol-independent method of multicasting with the WSAJoinLeaf API (discussed in the next section), but
as we will soon see, the setsockopt method is
much more flexible even though it is more closely tied to the protocol being
used.

IPv4

There are two socket options that control joining and leaving
groups: IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP. The socket option level is IPPROTO_IP. The input parameter is a struct ip_mreq structure, which is defined as

struct ip_mreq {
   struct in_addr imr_multiaddr;   /* IP multicast address of group */
   struct in_addr imr_interface;   /* local IP address of interface */
};

The imr_multiaddr field
is the 32-bit IPv4 address of the multicast group in network-byte order and
imr_interface is the 32-bit IPv4 address of
the local interface on which to join the multicast group (also specified in
network-byte order). The following code snippet illustrates joining a multicast
group.

SOCKET			      s;
SOCKADDR_IN    localif;
struct ip_mreq mreq;

s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

localif.sin_family = AF_INET;
localif.sin_port   = htons(5150);
localif.sin_addr.s_addr = htonl(INADDR_ANY);
bind(s, (SOCKADDR *)&localif, sizeof(localif));

mreq.imr_interface.s_addr = inet_addr("157.124.22.104");
mreq.imr_multiaddr.s_addr = inet_addr("234.5.6.7");

setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, 
sizeof(mreq));

Note that the socket should be bound to the wildcard
address (INADDR_ANY) before joining the group. In this example, the socket is
joined to the multicast group 234.5.6.7 on the local interface 157.124.22.104.
Multiple groups may be joined on the same socket on the same or different
interface.

Once one or more multicast groups are joined, the IP_DROP_MEMBERSHIP option is used to leave a
particular group. Again, the struct ip_mreq
structure is the input parameter. The local interface and multicast group to
drop are the arguments of the structure. For example, given the code sample you
just saw, the following code drops the multicast group previously joined:

// Join the group as shown above

mreq.imr_interface.s_addr = inet_addr("157.124.22.104");
mreq.imr_multiaddr.s_addr = inet_addr("234.5.6.7");

setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&mreq, 
sizeof(mreq));

Finally, if the application exits or the socket is closed,
any multicast groups joined by that process or socket are cleaned up.

note

An IPv4 multicasting sample that uses setsockopt is provided on the companion CD in the
directory IP-SETSOCKOPT.

IPv4 with Multicast Sourcing

IP source multicasting is available on systems that support the
IGMPv3 protocol and allows a socket to join a multicast group on an interface
while specifying a set of source addresses to accept data from. There are two
possible modes in which a socket may join a group. The first is the INCLUDE mode, in which a socket joins a group
specifying N number of valid source addresses to accept data from. The other
mode is EXCLUDE, in which a socket joins a
group specifying to accept data from anyone except
the N source addresses listed. Depending on which mode is used, the socket
options differ.

To join a multicast group while using the INCLUDE mode, the socket options are IP_ADD_SOURCE_MEMBERSHIP and IP_DROP_SOURCE_MEMBERSHIP. The first step is to add
one or more sources. Both socket options take a struct ip_mreq_source structure, which is defined
as

struct ip_mreq_source {
   struct in_addr imr_multiaddr;   /* IP multicast address of group */
   struct in_addr imr_sourceaddr;  /* IP address of source          */
   struct in_addr imr_interface;   /* local IP address of interface */
};

The imr_multiaddr and
imr_interface fields are the same as in the
struct ip_mreq structure. The new field imr_sourceaddr specifies the 32-bit IP address of
the source to accept data from. If there are multiple valid sources, then the
IP_ADD_SOURCE_MEMBERSHIP is called again with
the same multicast address and interface with the other valid source. The
following code sample joins a multicast group on a local interface with two
valid sources:

SOCKET                s;
SOCKADDR_IN           localif;
struct ip_mreq_source mreqsrc;

s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

localif.sin_family = AF_INET;
localif.sin_port   = htons(5150);
localif.sin_addr.s_addr = htonl(INADDR_ANY);
bind(s, (SOCKADDR *)&localif, sizeof(localif));

mreqsrc.imr_interface.s_addr = inet_addr("157.124.22.104");
mreqsrc.imr_multiaddr.s_addr = inet_addr("234.5.6.7");
mreqsrc.imr_sourceaddr.s_addr = inet_addr("172.138.104.10");

setsockopt(s, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP,
 		(char *)&mreqsrc, sizeof(mreqsrc));

mreqsrc.imr_sourceaddr.s_addr = inet_addr("172.141.87.101");

setsockopt(s, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP,
		(char *)&mreqsrc, sizeof(mreqsrc));

To remove a source from the INCLUDE set, the IP_DROP_SOURCE_ MEMBERSHIP is called with the
multicast group, local interface, and source to be removed.

To join a multicast group that excludes one or more sources, the
multicast group is joined with IP_ADD_MEMBERSHIP. Using IP_ADD_MEMBERSHIP to join a group is equivalent to
joining a group in the EXCLUDE mode except
that no one is excluded. Data sent to the joined group is accepted regardless of
the source. Once the group is joined, then the IP_BLOCK_SOURCE option is called to exclude the
given source. Again, the struct ip_mreq_source
structure is the input parameter that specifies the source to block. The
following example joins a group and then excludes a single source:

SOCKET                s;
SOCKADDR_IN           localif;
struct ip_mreq        mreq;
struct ip_mreq_source mreqsrc;

s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

localif.sin_family = AF_INET;
localif.sin_port   = htons(5150);
localif.sin_addr.s_addr = htonl(INADDR_ANY);
bind(s, (SOCKADDR *)&localif, sizeof(localif));

// Join a group - the filter is EXCLUDE none
mreq.imr_interface.s_addr = inet_addr("157.124.22.104");
mreq.imr_multiaddr.s_addr = inet_addr("234.5.6.7");

setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, 
 		sizeof(mreq));

mreqsrc.imr_interface = mreq.imr_interface;
mreqsrc.imr_multiaddr = mreq.imr_multiaddr;
mreqsrc.imr_sourceaddr.s_addr = inet_addr("172.138.104.10");

setsockopt(s, IPPROTO_IP, IP_BLOCK_SOURCE, (char *)&mreqsrc, 
 		sizeof(mreqsrc));

If after some point, the application wishes to accept data from
a source previously blocked, it may remove that source from the exclude set by
calling setsockopt with IP_UNBLOCK_SOURCE. A struct ip_mreq_source is the input parameter that
specifies the source to accept data from.

note

An IPv4 source multicasting sample that uses setsockopt is provided on the companion CD in the
directory IP-SOURCE.

 

抱歉!评论已关闭.