IP Multicast
Initiative (IPMI) Writing IP Multicast-enabled ApplicationsAn IP Multicast Initiative White Paper A technical description of IP Multicast APIs, and an overview of application requirements for their use Scope
Of This Document Microsoft Word Version -- PDF Version | ||||||||||||||||||||||||||
Scope Of This Document | ||||||||||||||||||||||||||
This document describes how to
multicast-enable an application. This includes an overview of the types of
applications that can benefit from multicast-enabling, the requirements
for their eligibility, and a detailed description of the application
programming interfaces (APIs) available for PC, Macintosh, and Unix
platforms. It also briefly discusses the considerations of address and
port usage, and scheduling-to avoid conflicts with other multicast
applications. Finally, it considers future application enhancements to
take advantage of RSVP, the quality of service protocol.
The intended audience is primarily application developers and project managers. The content is highly technical in nature, and makes a number of assumptions about the reader. It assumes an understanding of the mechanics of IP multicast from a host perspective (as described in the "How Multicast Works" white paper), it assumes familiarity with TCP/IP transport concepts-the differences between stream-oriented TCP connections and message-based UDP datagrams-and it assumes familiarity with standard network APIs.
| ||||||||||||||||||||||||||
Applications that can benefit from Multicast | ||||||||||||||||||||||||||
We characterize the applications
that can benefit most by adding multicast capabilities by the fact they
distribute data among multiple network hosts simultaneously, rather than
only exchanging data with only one host at a time. Two models of data
distribution exist: one-to-many, and many-to-many. There
are numerous examples of applications that implement these
models.
A one-to-many application sends the same information to many receivers simultaneously. The data flow is one-way, from a single sender. An application that sends time-critical, real-time information-like stock quotes-is an ideal example of a one-to-many application that can benefit from multicast. Applications that send news and weather, and other less-immediate, but widely distributable information, are other good examples. The analogous technical model is broadcast radio, and television. The types of content these applications typically send, and the schedule coordination requirements are analogous also. A many-to-many application is one that shares information with a number of machines simultaneously. In other words, in many-to-many applications the data flow is bi-directional. Each receiver is also a sender, so in effect, each many-to-many application acts as a one-to-many application (sending) and a many-to-one (receiving). Other more specialized applications that don't obviously fit the data distribution models can benefit from multicast as well. For instance, applications that synchronize information among multiple network hosts-including exchange of internal application states, as well as data-are multicast candidates. Applications that attempt to discover other applications, or services, could use multicast also.
| ||||||||||||||||||||||||||
Application Requirements for Multicast-enabling | ||||||||||||||||||||||||||
It is possible to
create an application that does data distribution without using
multicast. Many such applications exist. They use unicast datagram or
connection-oriented stream transports to distribute data to each host
individually. But as other IPMI white papers describe, these applications
are less than optimal in many respects.
Non-multicast data distribution applications duplicate the data they send to each receiver and as a result of this duplication-and the network bandwidth it wastes-these applications cannot scale to service increasing numbers of receivers. They cannot distribute in a timely manner either, since the delivery to each host has to be serialized in some fashion. To illustrate, consider the logistics of newspaper delivery, versus news radio broadcasts. Many existing data distribution applications can be easily adapted to use multicast, but others may require significant redesign. The ideal candidates are applications that currently use connection-less datagram transport (e.g. UDP). These are easiest to adapt, since they already use a message-oriented, "unreliable" transport. On the other hand, applications that utilize connection-oriented, datastream protocols (e.g. TCP) need significant work. They usually depend on the reliable data delivery capabilities-acknowledged delivery, sequenced data, no duplicates--that the transport provides, so the application needs to be redesigned to implement these capabilities at the application layer. Some datagram applications have implemented unicast reliability at the application layer, but reliable multicast algorithms have very different requirements. One cannot simply implement datagram versions of what TCP does. You can imagine the problem caused by acknowledgments from many receivers sent at once to a single sender (implosion). Implementing a reliable multicast transport is a difficult challenge, but certainly possible. There are a number of implementations available that offer reliable multicast, including some commercial products that utilize it quite effectively for applications like multicast file transfer. Some of these algorithms have been proposed to the IETF as possible standards. None have been fully embraced yet; reliable multicast is a fairly recent area of research and development. Scalability and congestion avoidance issues on the Internet are a primary focus in these efforts. The IPMI "Higher Level Protocols used with IP Multicast" white paper discusses reliable multicast in more detail. As a result of this and the complex algorithms involved, we will not cover the topic of reliable multicast applications any further in this document. Adapting unicast datagram applications to multicast Assuming you are adapting an application that currently uses unicast datagrams, the multicast-enabling requirements depend on the type of data distribution the application does, the application's role in host-to-host communications, and the desired operating characteristics. Table 1 summarizes the most significant considerations, and provides a brief description of what's required in an application.
Table 1: Summary of minimum multicast modifications RFC 1112, "Host Extensions for IP Multicasting," describes what is required of a host's IP implementation to support multicast. In this description, it also prescribes the default behavior of multicast applications:
To allow an application to modify the default behavior, RFC 1112 recommends a number of APIs for multicast support:
The same year he wrote RFC 1112 (1989), Steve Deering also authored a paper called "IP Multicast Extensions for 4.3BSD UNIX and related systems." In this paper, Steve describes the Berkeley Sockets multicast APIs he implemented, which are the same APIs still in use today. They provide the functionality described above, and are now the de facto standard multicast APIs. Other APIs have also emerged for other network platforms, and they all provide basically the same functionality described by RFC 1112.
| ||||||||||||||||||||||||||
Standard Multicast APIs | ||||||||||||||||||||||||||
As we mentioned, multicast APIs
are currently available for a number of platforms. All are derived from
the requirements set forth by RFC 1112, so they all have similar
functionality. The APIs we describe in the remainder of this section are
for
Berkeley Sockets Multicast APIs The Berkeley Sockets Multicast APIs are the same as those described by Steve Deering (as mentioned earlier). They complement the existing Berkeley Sockets APIs, which were designed to allow creating of network applications using virtually any network protocol suite, including TCP/IP, the so-called "Internet address family." All of the Berkeley multicast APIs use the setsockopt() "socket option" function to initiate their actions (and for some options, the getsockopt() function is also available to retrieve the current setting).
Table 2: Summary of BSD set/getsockopt() multicast commands The setsockopt() IP_ADD_MEMBERSHIP function is the most significant of all the APIs, in several respects. It is required to receive any datagrams destined for the specified multicast (group) address. Unlike other socket options, it actually initiates some network activity; it causes the underlying IP protocol stack to issue an IGMP (Internet Group Message Protocol) host membership report to notify the local router(s) of the group membership, as prescribed by RFC 1112. For an example of how to use these de facto standard multicast APIs, see the "Code Samples" section of this white paper. Windows Sockets Multicast APIs Windows Sockets version 2 (a.k.a. WinSock 2), is a set of APIs designed for 32-bit Microsoft Windows platforms for creating network applications using virtually any network protocol. WinSock 2 is a superset of WinSock version 1.1, which was itself both a superset of Berkeley Sockets (new Windows-specific functions were added), and subset of Berkeley Sockets (not all APIs were supported; in particular, many ioctl()s were not supported). WinSock 2 supports the Berkeley Sockets compatible TCP/IP protocol-specific APIs, as described above (and also described in the TCP/IP section of the "WinSock 2 Protocol-Specific Annex"). However, WinSock 2 has also defined a set of new protocol-independent (non-IP-specific) multipoint APIs that can support IP multicast, as shown in Table 3.
Table 3: Summary of WinSock 2's protocol-independent multipoint APIs To allow for qualification of various multipoint models, WinSock 2 has defined the concepts of a "data plane" and "control plane," each of which can be "rooted" or "non-rooted,". We won't go into detail about what these concepts mean here. Suffice it to say that IP multicast always has non-rooted data and control planes. You specify these roles when you request a multipoint socket using WSASocket(). The WSAEnumProtocols() function returns detailed descriptions of the protocols currently installed in a system in an array of protocol information structures (WSAPROTOCOL_INFO). Among the flags to describe the services provided by the IP/UDP protocol, the bit-flag XP1_SUPPORT_MULTIPOINT in the dwServiceFlags1 field indicates IP multicast support. Lastly, notice that an API to leave a multicast group is missing from this list. The only protocol-independent API to provide a way to leave a multicast group after joining, is to close a socket. We have an example that shows how to use the protocol-independent multipoint APIs for IP multicast, see the "Code Samples" section of this white paper. Open Transport/TCP Multicast APIs Open Transport is a set of APIs recently defined by Apple Computer, Inc. as their new standard for creating network applications on Macintosh computers using virtually any communications device, or network protocol, including TCP/IP. Open Transport is a superset of the XTI standard networking API defined by the X/Open Unix vendor consortium (and XTI is itself a superset of TLI, another de facto standard network API). Like Berkeley Sockets and WinSock, Open Transport (OT) is protocol-independent, but also includes some protocol-specific APIs for support of IP multicast. In OT terms, these extensions are called an "option management scheme." All of these IP multicast extensions use the OptionManagement() function (the standard C interface version is called OTOptionManagement()). As shown in Table 4, they have the same names as the Berkeley Sockets APIs, and provide the same functionality. However, not all of the Berkeley Sockets multicast options are supported.
Table 4: Summary of Open Transport's OptionManagement multicast APIs For an example of how to use these Open Transport multicast APIs, see the "Code Samples" section of this white paper.
| ||||||||||||||||||||||||||
Multicasting with care | ||||||||||||||||||||||||||
Multicast is great, and allows for
many powerful and flexible applications that are relatively kind to the
network, since-among other things-they can send a single data stream to
multiple receivers simultaneously. However, it is still possible to abuse
a network with multicast applications. To minimize the impact that
applications have on a network, conscientious multicast application
developers (and users) must always:
Port and Address Considerations With multicast applications, one refers to multicast sessions. The destination multicast address and destination port are, in effect, the session identifiers. Any multicast application can send to and receive from different unicast addresses and port number within a single session (a multicast address is never used as a source address). In this case, a receiver can identify the sender of any datagram it receives by the source address and port number. Hence, the 5-tuple of 1) protocol, 2) local address, 3) local port number, 4) remote address and 5)remote port number comprise the unique value that identifies a message flow-all of the datagrams from any particular sender--within a session. The session identifiers are an important consideration in the design and execution of a multicast application. On a private network, this is less of an issue, but on the Internet (or MBone) it is of paramount importance. Since any two (or more) applications using the same session parameters can interfere with each other's message flow-in effect, introducing garbage data, respectively-application developers must be careful in the choice of multicast address, port number, as well as when and where the application is used on the network. On the MBone, the "session directory" application (sd) manages-and "advertises"-session schedules (on 224.2.2.2, port 4000). This application not only makes the multicast schedule widely available, but also assigns a unique multicast address and port number to each multicast application session (actually, to each message flow in a session). In other words, it manages the address/port space to help you to avoid conflicts. The use of sd is encouraged, if not required, on the Mbone (note: The IPMI "Higher Level Protocols Used with Multicast" white paper has more information on group setup protocols). There is no way for an application to select a multicast address with complete safety (avoiding collisions), without using a "centralized" management scheme, like session directory. There is no way for an application to safely check whether anyone else is using a multicast address. Attempts at listening on an address for traffic, querying with IGMP for members, and trying to implement or listen to routing protocols are all strategies with limitations, difficulties and dangers. In some (relatively rare) cases, the assignment of one or more permanent IP multicast addresses is in order. For example, standardized applications (like sd), and content providers with constant media streams warrant permanent multicast addresses. Anyone who feels they can justify an address assignment, can apply for one with the Internet Assigned Numbers Authority (IANA). Among other things, IANA manages the multicast address space. They also maintain port number assignments for all of the Internet's well-known services (for more information, see http://www.isi.edu/iana).
| ||||||||||||||||||||||||||
Multicast API Limitations | ||||||||||||||||||||||||||
Interoperability is not an API issue. The APIs
are well-defined and relatively simple for IP multicast. The host
implementations with full IP multicast support, all support the Internet
Group Message Protocol (IGMP), according to RFC 1112 (an overview of which
is covered in the IPMI white paper "How IP Multicast Works"). Virtually
all host implementations of TCP/IP protocol stacks provide multicast
support today. For those that do not, system patches are widely
available.
Although the support of multicast on an internetwork is ultimately dependent on the multicast router protocols in use-their interoperability and ubiquity-these routing protocols do not directly affect the host implementations or multicast APIs. Conversely, the multicast APIs in a multicast host implementation have no direct effect over the router protocols either. This dichotomy between host and router responsibilities is good. It represents a division of labor that ultimately simplifies multicast application development on hosts. However, it also sacrifices some control in multicast applications, or application "self-awareness." For example, as a result there are no APIs to allow a multicast application to determine the multicast capability of other hosts or routers. There are no standard APIs (or protocols) available to discover how many and which hosts are receiving multicast traffic, to find the routes to those hosts, or to discover anything else about those routes. The only way for a multicast application to retrieve this information is to either implement an application protocol to exchange statistics between group members (as RTCP does; for more information see the "Higher Level Protocols used with IP Multicast" white paper). This is not a large problem, but it is one to be aware of. If you need to know this type of information, you will need to plan on implementing support for it in your applications yourself. In particular, you'll need to implement a protocol by which session members can exchange performance, and other useful session management information.
| ||||||||||||||||||||||||||
Future application needs - Quality of Service | ||||||||||||||||||||||||||
Quality of service is synonymous
with bandwidth reservation. Requesting that a portion of the available
network bandwidth between a sender and receiver be dedicated to each of an
application's message flows. This is of particular appeal to applications
that send audio and video, or other "real-time," high-bandwidth, or
mission-critical data, where reliable and consistent delivery is a
concern.
The IETF is close to finalizing version 1 of the ReSerVation Protocol (RSVP) for use with the Internet Protocol (both IPv4 and IPv6). Although it is still somewhat experimental, beta implementations for hosts and routers are available. Some Internet service providers (ISPs) are also providing experimental RSVP support. Use with multicast has always been a focus of RSVP designers. Receivers initiate reservation requests, which flow "upstream" to the sender. The local system, and each router on the upstream path, can accept or reject reservation requests. Routers also "merge" reservation requests from multiple downstream receivers, as they propagate the requests toward the sender. A receiver application can make a reservation request for itself, or on behalf of another application. To do so, requires a set of RSVP-relevant APIs. There are currently a number of standard RSVP API proposals that multicast application programmers should be aware of for possible future enhancement of their applications:
| ||||||||||||||||||||||||||
Concluding Remarks | ||||||||||||||||||||||||||
IP Multicast enables many new
types of applications and reduces network congestion and server loads.
This document began by describing the types of applications that can most
benefit from multicast, and what is required for an application to be
eligible for multicast-enabling.
Converting unicast datagram applications to take advantage of multicast requires the use of only a few multicast-specific APIs to override some of the defaults in a unicast datagram application. Senders need only send to a multicast address and adjust the IP time-to-live according to the desired scope, and possibly disable the loopback. A receiver need only join a multicast group. On the other hand, converting applications that currently use reliable, connection-oriented protocols (TCP) to multicast (UDP) can be a significant challenge. We only had a brief discussion of this topic; some effective products shipping already, but standard protocols for reliable multicast are still a subject of research. We also considered what it takes to make sure your multicast application remains network friendly. And finally, we briefly mentioned near-future APIs relevant to many multicast applications, to provide the bandwidth reservation (using RSVP).
| ||||||||||||||||||||||||||
Code Samples | ||||||||||||||||||||||||||
This section contains three code
samples, that demonstrate how to use each of the three APIs described in
the "Standard Multicast APIs" section of this white paper. Each sample
does basically the same thing (and they can communicate with each other):
Each application acts as both a sender and receiver (as both a client
application and a server, per se):
When you start a second instance of any of these test applications, the datagram that the second instance sends will trigger the first to send again, and that will trigger the second instance to send again, and so on, in a loop. In other words, two (or more) applications running have a Ping-Pong effect between each other. Please use with caution! This sample program is for demonstration only. The number of iterations is limited purposefully, since this application is capable of generating significant network traffic. Because it sends a datagram in immediate response to every datagram it receives, without a limit this application is capable of flooding a network with traffic. Also note that, for brevity, we have removed error checking from the function calls in these samples. We strongly encourage you to check the returns from all function calls in your own application code. Application Requirements To use this application on any system, it must be IP Multicast-capable. Each of the three platforms we deal with here fulfill this in different ways:
It is not necessary to be connected to the MBone to use these applications, nor even to have a multicast capable router installed. You can use these applications on a single subnet between hosts. In fact, you can even use these on a single host--without any active network connection, in some cases--if you disable loopback in the application. Berkeley Sockets multicast code sample The following code snippet illustrates the use of all the Berkeley Sockets the multicast APIs, except IP_MULTICAST_IF. #include <sys/types.h> /* include files for IP Sockets */ #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define BUFSIZE 1024 #define TTL_VALUE 2 #define TEST_ADDR "234.5.6.7" #define TEST_PORT 3456 #define LOOPMAX 10 int main(){ struct sockaddr_in stLocal, stTo, stFrom; char achIn[BUFSIZE]; char achOut[] = "Message number: "; int s; struct ip_mreq stMreq; int iTmp, i; /* get a datagram socket */ s = socket(AF_INET, SOCK_DGRAM, 0); /* avoid EADDRINUSE error on bind() */ iTmp = TRUE; setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&iTmp, sizeof(iTmp)); /* name the socket */ stLocal.sin_family = AF_INET; stLocal.sin_addr.s_addr = htonl(INADDR_ANY); stLocal.sin_port = htons(TEST_PORT); bind(s, (struct sockaddr*) &stLocal, sizeof(stLocal)); /* join the multicast group. */ stMreq.imr_multiaddr.s_addr = inet_addr(TEST_ADDR); stMreq.imr_interface.s_addr = INADDR_ANY; setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&stMreq, sizeof(stMreq)); /* set TTL to traverse up to multiple routers */ iTmp = TTL_VALUE; setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&iTmp, sizeof(iTmp)); /* disable loopback */ iTmp = FALSE; setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&iTmp, sizeof(iTmp)); /* assign our destination address */ stTo.sin_family = AF_INET; stTo.sin_addr.s_addr = inet_addr(TEST_ADDR); stTo.sin_port = htons(TEST_PORT); for (i=0;i<LOOPMAX;i++) { int addr_size = sizeof(struct sockaddr_in); static iCounter = 1; int i; /* send to the multicast address */ itoa(iCounter++, &achOut[16], 10); i = sendto(s, achOut, sizeof(achOut), 0,(struct sockaddr*)&stTo, addr_size); if (i < 0) { perror("sendto() failed\n"); exit(1); } i = recvfrom(s, achIn, BUFSIZE, 0, (struct sockaddr*)&stFrom, &addr_size); if (i < 0) { perror("recvfrom() failed\n"); exit(1); } printf("From host:%s port:%d, %s\n", inet_ntoa(stFrom.sin_addr), ntohs(stFrom.sin_port), achIn); } } /* end main() */ WinSock 2 protocol-independent multicast-code sample The following code sample uses function calls described in the Windows Sockets 2 Application Programming Interface specification. Many of these functions are protocol-independent equivalents of Berkeley Sockets functions, and could be replaced by them. Actually, because WinSock 2 also supports the protocol-specific BSD multicast APIs, with the addition of calls to WSAStartup() and WSACleanup() at the beginning and end, the BSD sample program above can be used with WinSock 2 implementations. Note: At the time of this writing, WinSock 2 is shipping as the native network interface on Windows NT version 4, and is in beta for Windows 95. The calls to disable loop back (using either setsockopt() IF_MULTICAST_LOOP or WSAIoctl() SIO_MULTIPOINT_LOOPBACK) always fail, as does the call to WSIoctl() SIO_MULTICAST_SCOPE (the equivalent setsockopt() IP_MULTICAST_TTL does work, however). Since you cannot disable loopback, you need only run a single instance on a machine to see it in action sending to and receiving from itself. #include <winsock2.h> #define BUFSIZE 1024 #define MAXADDRSTR 16 #define LOOPMAX 10 int main() { int nRet, i; int nIP_TTL = 2; BOOL bFlag; DWORD dFlag; DWORD cbRet; int iLen = MAXADDRSTR; char strDestMulti[MAXADDRSTR] = "234.5.6.7"; SOCKADDR_IN stSrcAddr, stDestAddr; SOCKET hSock, hNewSock; u_short nDestPort = 3456; WSABUF stWSABuf; char achInBuf [BUFSIZE]; char achOutBuf[] = "Message number: "; WSADATA stWSAData; /* init WinSock */ WSAStartup(0x0202, &stWSAData); /* convert address string to value */ stDestAddr.sin_family = AF_INET; nRet = WSAStringToAddress ( strDestMulti, /* address string */ AF_INET, /* address family */ NULL, /* protocol info structure */ (LPSOCKADDR)&stDestAddr,/* socket address string */ &iLen); /* length of socket structure */ /* get a socket */ hSock = WSASocket(AF_INET, SOCK_DGRAM, 0, (LPWSAPROTOCOL_INFO)NULL, 0, WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF); /* allow reuse of the local port number */ bFlag = TRUE; nRet = setsockopt(hSock, SOL_SOCKET, SO_REUSEADDR, (char *)&bFlag, sizeof (bFlag)); /* name the socket */ stSrcAddr.sin_family = PF_INET; stSrcAddr.sin_port = htons (nDestPort); stSrcAddr.sin_addr.s_addr = INADDR_ANY; nRet = bind (hSock, (struct sockaddr FAR *)&stSrcAddr, sizeof(struct sockaddr)); /* byte swap host to network order */ stDestAddr.sin_family = PF_INET; nRet = WSAHtons( hSock, /* socket */ nDestPort, /* host order value */ &(stDestAddr.sin_port)); /* network order value */ /* set the IP TTL */ nRet = WSAIoctl (hSock, /* socket */ SIO_MULTICAST_SCOPE, /* IP Time-To-Live */ &nIP_TTL, /* input */ sizeof (nIP_TTL), /* size */ NULL, /* output */ 0, /* size */ &cbRet, /* bytes returned */ NULL, /* overlapped */ NULL); /* completion routine */ /* disable loopback */ bFlag = FALSE; nRet = WSAIoctl (hSock, /* socket */ SIO_MULTIPOINT_LOOPBACK, /* turn loopBack off */ &bFlag, /* input */ sizeof (bFlag), /* size */ NULL, /* output */ 0, /* size */ &cbRet, /* bytes returned */ NULL, /* overlapped */ NULL); /* completion routine */ /* join the multicast group */ NewSock = WSAJoinLeaf (hSock, /* socket */ (PSOCKADDR)&stDestAddr, /* multicast address */ sizeof (stDestAddr), /* length of addr struct */ NULL, /* caller data buffer */ NULL, /* callee data buffer */ NULL, /* socket QOS setting */ NULL, /* socket group QOS */ JL_BOTH); /* do both: send and recv */ /* send and receive loop */ for (i=0;i<LOOPMAX;i++) { static iCounter = 1; /* send data */ stWSABuf.buf = achOutBuf; stWSABuf.len = lstrlen(achOutBuf); cbRet = 0; itoa(iCounter++, &achOutBuf[16], 10); nRet = WSASendTo (hSock, /* socket */ &stWSABuf, /* output buffer structure */ 1, /* buffer count */ &cbRet, /* number of bytes sent */ 0, /* flags */ (struct sockaddr*)&stDestAddr,/* destination address */ sizeof(struct sockaddr), /* size of addr structure */ NULL, /* overlapped structure */ NULL); /* overlapped callback */ if (nRet == SOCKET_ERROR) { printf("WSASendTo() failed, Err: %d\n", WSAGetLastError()); } stWSABuf.buf = achInBuf; stWSABuf.len = BUFSIZE; cbRet = 0; iLen = sizeof (stSrcAddr); dFlag = 0; nRet = WSARecvFrom (hSock, /* socket */ &stWSABuf, /* input buffer structure */ 1, /* buffer count */ &cbRet, /* number of bytes recv'd */ &dFlag, /* flags */ (struct sockaddr *)&stSrcAddr,/* source address */ &iLen, /* size of addr structure */ NULL, /* overlapped structure */ NULL); /* overlapped callback */ if (nRet == SOCKET_ERROR) { printf("WSARecvFrom() failed, Err:%d\n", WSAGetLastError()); } else { /* convert address value to string */ u_short nPort = 0; char achAddr[BUFSIZE]; iLen = BUFSIZE; nRet = WSAAddressToString( (struct sockaddr *)&stSrcAddr,/* source address */ sizeof(stSrcAddr), /* size of addr struct */ NULL, /* protocol info */ achAddr, /* address string */ &iLen); /* addr string buf len */ /* convert from network to host byte order */ nRet = WSANtohs(hSock, /* socket */ stSrcAddr.sin_port, /* host order value */ &nPort); /* network order value */ } printf ("Message from %s, port %d: %s\r\n", achAddr[0] ? achAddr : "??", nPort, achInBuf); } } /* end for(;;) */ /* tell WinSock we're leaving */ WSACleanup(); return (0); } /* end main() */ Open Transport multicast code sample The Open Transport /TCP Developer Note specification from Apple Computer describes IP protocol-specifics, including the APIs for IP multicast support. These APIs differ from BSD Sockets, but they are modeled after BSD Sockets to an extent. There are many equivalencies: Most importantly, the multicast options used by the OTOptionManagement() function, are the same as the setsockopt() multicast options. #include <stdio.h> #include <OpenTransport.h> #include <OpenTptInternet.h> #define BUFSIZE 128 #define TTL_VALUE 2 #define TEST_ADDR 0xEA050607; /* 234.5.6.7 */ #define TEST_PORT 3456 #define IADDRLEN 16 void main() { int i; OSStatus err; EndpointRef udp_ep = nil; UInt8 buf[BUFSIZE]; UInt8 bufOut = "Message number: "; InetAddress IAddrBuf; /* same as BSD struct sockaddr_in */ InetAddress src_addr, dest_addr; TBind BindReq, BindRet; TOption* OptBuf; TOptMgmt OptReq, OptRet; TIPAddMulticast MCAddr; /* same as BSD struct mreq */ TUnitData udata; /* Init Open Transport */ err = InitOpenTransport(); /* get a datagram endpoint */ *ep = OTOpenEndpoint( OTCreateConfiguration(kUDPName), 0, nil, &err) /* name the endpoint */ BindReq.addr.len = IADDRLEN; BindReq.addr.buf = &IAddrBuf; OTInitInetAddress (&IAddrBuf, TEST_PORT, 0L); err = OTBind (*ep, &BindReq, &BindRet); /* join the multicast group */ OptBuf = (*TOption)buf; OptBuf->level = INET_IP; OptBuf->name = IP_ADD_MEMBERSHIP; OptBuf->len = BUFSIZE; OptBuf->status = 0; *(TIPAddMulticast *)OptBuf->value = &MCAddr; MCAddr.multicastGroupAddress = TEST_ADDR; MCAddr.multicastAddress = 0L; OptReq.opt.buf = &MCAddr; OptReq.opt.len = sizeof(TIPAddMulticast); OptReq.opt.flags = T_CHECK; OptRet.opt.buf = buf; OptRet.opt.maxlen = BUFSIZE; err = OTOptionManagement (ep, &OptReq, &OptRet); /* set TTL to traverse multiple routers */ OptBuf->level = INET_IP; OptBuf->name = IP_MULTICAST_TTL; OptBuf->len = BUFSIZE; OptBuf->status = 0; *(UInt8 *)OptBuf->value = TTL_VALUE; OptReq.opt.buf = buf; OptReq.opt.len = kOTOneByteOptionSize; OptReq.opt.flags = T_CHECK; OptRet.opt.buf = buf; OptRet.opt.maxlen = kOTFourByteOptionSize; err = OTOptionManagement (ep, &OptReq, &OptRet); /* disable loopback */ OptBuf->level = INET_IP; OptBuf->name = IP_MULTICAST_LOOP; OptBuf->len = BUFSIZE; OptBuf->status = 0; *(UInt8 *)OptBuf->value = 0; OptReq.opt.buf = buf; OptReq.opt.len = kOTOneByteOptionSize; OptReq.opt.flags = T_CHECK; OptRet.opt.buf = buf; OptRet.opt.maxlen = kOTFourByteOptionSize; err = OTOptionManagement (ep, &OptReq, &OptRet); /* assign our destination address */ OTInitInetAddress (&dest_addr, TEST_PORT, TEST_ADDR); for (i=0; i<MAXLOOP; i++) { OTResult look; static iCounter = 1; udata.addr.len = sizeof(dest_addr); udata.addr.buf = (unsigned char *) &dest_addr; udata.opt.len = 0; udata.opt.buf = nil; itoa(iCounter++, &bufOut[16], 10); udata.udata.len = sizeof(bufOut); udata.udata.buf = bufOut; err = OTSndUData (ep, &udata); if (err != noErr) { printf ("OTSndUData() failed: %d\n, err); } udata.addr.buf = (UInt8 *) &src_addr; udata.addr.maxlen = sizeof (struct InetAddress); udata.opt.buf = nil; udata.opt.maxlen = 0; udata.udata.buf = buf; udata.udata.maxlen = BUFSIZE; err = OTRcvUData (ep, &udata, nil); if (err == noErr) { printf ("From host: 0x%lx, %s\n", buf); } else { printf ("OTRcvUData() failed: %d\n, err); } } /* close the endpoint */ OTCloseProvider (ep); /* sign-off Open Transport */ CloseOpenTransport(); } /* end main() */ | ||||||||||||||||||||||||||
More Information | ||||||||||||||||||||||||||
IP Multicast Initiative
(IPMI)
There are many other technical aspects of IP Multicast and business benefits that were not discussed here. The IP Multicast Initiative web site at http://www.ipmulticast.com/ has a technical resource center which provides more background in-depth information including white papers and relevant RFC’s. The web site also offers a product and services directory and lists members of the IP Multicast Initiative who can be contacted for information and assistance. The IP Multicast Initiative provides marketing and educational services to promote the creation, use and deployment of multicast products and solutions. Supported by a growing number of the most important vendors in the IP Multicast arena, the Initiative and its services are managed and provided by Stardust.com, Inc. For more information about the Initiative and membership, or to see other white papers, contact Stardust.com at 408-879-8080 or visit the Initiative web site.
| ||||||||||||||||||||||||||
Useful References | ||||||||||||||||||||||||||
The following references are
recommended; many were used in the preparation of this document. The
authors are gratefully acknowledged.
Books
IETF RFCs
IETF RFCs (as of 11/96)
| ||||||||||||||||||||||||||
Rev:042997-01
© Copyright 1995-1997 Stardust Technologies, Inc. All Rights Reserved.
Stardust RESTRICTED RIGHTS LEGEND USE, DUPLICATION, OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO RESTRICTIONS AS SET FORTH IN SUBPARAGRAPH (c) (1) (ii) OF THE RIGHTS IN TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of Commercial Computer Software—Restricted Rights at 48 CFR 52.227-19, as applicable. Stardust Technologies Inc. 1901 S. Bascom Ave., Suite 333, Campbell, CA 95008 |