HPlogo HP 9000 Networking: BSD Sockets Interface Programmer's Guide > Chapter 5 Advanced Topics for Internet Datagram Sockets

Sending and Receiving IP Multicast Datagrams

» 

Technical documentation

Complete book in PDF

 » Table of Contents

 » Glossary

 » Index

IP multicasting provides a mechanism for sending a single datagram to a group of systems. Normally, only systems that have joined the multicast group process the datagrams.

Multicast datagrams are transmitted and delivered with the same "best effort" reliability as regular unicast IP datagrams. That is, the datagrams are not guaranteed to arrive intact at all members of the destination group or in the same order as the datagrams were sent.

Membership in a multicast group is dynamic. That is, systems can join and leave groups at any time. A system remains a member of a multicast group until the last socket that joined the group is closed or has dropped membership in the group. A system can be a member of more than one group at a time. A system that has multiple interfaces might be a member of the same group on each interface.

Sending IP Multicast Datagrams

IP multicasting is supported only for AF_INET sockets of type SOCK_DGRAM and only on networks for which the interface supports multicasting.

To send a multicast datagram, the application specifies an IP multicast address as the destination address in a sendto(2) call. For example:

#include <netinet/in.h>         
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = 12345;
servaddr.sin_addr.s_addr = inet_addr("224.1.2.3");
sendto(s, buf, buflen, 0, &servaddr, sizeof(servaddr));

It is not necessary for the system to join a multicast group in order to send multicast datagrams.

Each multicast datagram is sent from one network interface at a time, even if the system has joined the destination multicast group on more than one interface. The system administrator configures a default interface from which to send multicast datagrams. An application can override the default by setting a socket option IP_MULTICAST_IF to specify the outbound interface for datagrams sent through that socket.

Normally, multicast datagrams are sent only to systems directly connected to the same network that the sending interface is on. If multicast datagrams are intended for distant networks, a special multicast router must be present on the local and intermediate networks. A socket option IP_MULTICAST_TTL controls the number of intermediate systems through which a multicast datagram can be forwarded.

If a multicast datagram is sent to a port from which an application on the local system is reading, normally a copy of the datagram is looped back and delivered to the application. A socket option IP_MULTICAST_LOOP allows the sending application to disable loopback for datagrams sent through that socket.

Specifying the Outbound Interface IP_MULTICAST_IF

Normally, multicast datagrams are sent through the interface that is associated with the default route, if one is configured. Alternatively, the system administrator can configure other interfaces as the default multicast route and as the route for specific multicast groups.

The configured multicast routes should suffice for most applications. However, an application can override the default multicast route by setting the IP_MULTICAST_IF socket option. For example:

#include <netinet/in.h>         
struct in_addr addr;
addr.s_addr = inet_addr("192.1.2.3");
setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr));

If addr.s_addr is INADDR_ANY, subsequent outbound multicasts from the application are sent from the default interface. Otherwise, addr.s_addr must specify the IP address of a local network interface that supports multicasting.

Specifying the Scope of a Multicast IP_MULTICAST_TTL

By default, multicast datagrams are sent only to systems on a local network. If the multicast datagram is intended to be sent to distant networks, and if there is a special multicast router on the local network, the application can increase the scope of the multicast by using the IP_MULTICAST_TTL socket option. For example:

#include <netinet/in.h>         
unsigned char ttl = 64;
setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));

Note that ttl is an unsigned char. Any of the values 0 through 255 can be specified. If ttl is zero, the multicast is limited to the local system. If ttl is one, the multicast is limited to a local network. If ttl is two, the multicast can forwarded through at most one gateway; and so forth.

Disabling Loopback IP_MULTICAST_LOOP

Normally, if a multicast datagram is sent to a port from which an application on the local system is reading, a copy of the datagram is looped back and delivered to the application.

The IP_MULTICAST_LOOP socket option allows the sending application to disable loopback for datagrams sent through that socket. For example:

#include <netinet/in.h>         
unsigned char loop = 0;
setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));

Note that loop is an unsigned char. Usually, applications should not disable loopback. Disabling loopback provides only a modest improvement in system performance.

Receiving IP Multicast Datagrams

IP multicasting is supported only for AF_INET sockets of type SOCK_DGRAM and only on networks for which the interface supports multicasting.

In order to receive multicast datagrams, an application must bind to the port number to which multicast datagrams will be sent. If an application binds to the address INADDR_ANY, it may receive all datagrams that are sent to the port number. If the application binds to a multicast group address, it may receive only datagrams sent to that group and port number.

Additionally, the system must join the multicast group on the interface on which the multicast datagrams arrive. An application can request that the system join a group by using the IP_ADD_MEMBERSHIP socket option.

An application can join up to IP_MAX_MEMBERSHIPS multicast groups on each socket. Currently, this is defined to be 20 in <netinet/in.h>. However, each network interface may impose a smaller system-wide limit because of interface resource limitations and because the system uses some link-layer multicast addresses. For example, the E/ISA interface card is limited to 16 multicast addresses, and the system uses two of those. So all applications in the system can join at most 14 unique multicast groups on each E/ISA interface.

An application automatically leaves a multicast group when it terminates, either normally or abnormally. Alternatively, the application can leave a group by using the IP_DROP_MEMBERSHIP socket option. However, the system remains a member of a multicast group as long as at least one application is a member.

If more than one application binds to the same port number on a system, each application must set the SO_REUSEPORT socket option before binding to the port. In that case, every application will receive all multicast datagrams sent to the port number.

Joining a Multicast Group IP_ADD_MEMBERSHIP

In order to receive multicast datagrams, a system must join the multicast group. An application can request that the system join a group by using the IP_ADD_MEMBERSHIP socket option. For example:

#include <netinet/in.h>         
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr("224.1.2.3");
mreq.imr_interface.s_addr = INADDR_ANY;
setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));

Each membership is associated with only one interface, and it is possible to join the same multicast group on more than one interface. If imr_interface is INADDR_ANY, the membership is joined on the system default interface. Otherwise, imr_interface should be the IP address of a local interface.

Leaving a Multicast Group IP_DROP_MEMBERSHIP

An application automatically leaves a multicast group when it terminates, either normally or abnormally. Alternatively, the application can leave a group by using the IP_DROP_MEMBERSHIP socket option. For example:

#include <netinet/in.h>         
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = net_addr("224.1.2.3");
mreq.imr_interface.s_addr = INADDR_ANY;
setsockopt (s, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));

Note that imr_interface must match the field that was used when the IP_ADD_MEMBERSHIP socket option was specified for imr_multiaddr.

Sharing a Multicast Port SO_REUSEPORT

If more than one application may bind to the same port number on a system, each application must set the SO_REUSEPORT socket option before binding to the port. For example:

#include <netinet/in.h>         
int reuse = 1;
setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(reuse));
© 1997 Hewlett-Packard Development Company, L.P.