Memra

Multicast: one send, many receivers

◈ 6 cards

Group addresses in 224.0.0.0/4, MulticastSocket as a DatagramSocket with joinGroup and leaveGroup, TTL as a scope dial, and why multicast stops at the edge of an administered network.

One send, many receivers, decided by the network

Everything so far has been unicast: one sender, one receiver, one clearly identified pair. Broadcast, which you switched on with setBroadcast(true) in the last lesson, is the other extreme — every host on the segment gets a copy whether it wants one or not, which is why routers refuse to forward broadcasts and why the technique cannot scale past a subnet.

Multicast is the middle. The sender transmits once, to a group address, and the network duplicates the packet only where paths to interested receivers diverge. If forty machines on one LAN are receiving a feed, exactly one copy crosses the link to that LAN and the local router fans it out. Add a second site and the stream splits at the last shared router, not at the source.

The crucial word is interested. A host receives a group's traffic only after it has explicitly joined the group. Membership is open and dynamic — hosts join and leave at will, and the sender neither knows nor cares who is listening. It never addresses a receiver. It addresses the group.

The address range is the group

A multicast group is an address. In IPv4 the groups are 224.0.0.0/4 — everything from 224.0.0.0 to 239.255.255.255, the addresses whose first four bits are 1110. IPv6 uses ff00::/8. There is no registration step for the ordinary ranges: pick an address, construct an InetAddress for it, and start sending.

Three ranges are worth knowing by sight:

  • 224.0.0.0 – 224.0.0.255 is link-local and reserved for infrastructure — routing protocols, gateway discovery, mDNS on 224.0.0.251. Routers never forward this range, whatever TTL you set.
  • 224.0.1.x and 224.1/224.2 hold permanently assigned addresses handed out by IANA, such as 224.0.1.1 for NTP.
  • 239.0.0.0 – 239.255.255.255 is administratively scoped: reserved for use inside one organisation, bounded by policy on the routers rather than by hop count. This is where your own application groups belong.

MulticastSocket is a DatagramSocket with two extra verbs

java.net.MulticastSocket extends DatagramSocket, so send, receive, setSoTimeout and close are the inherited methods you already know, and the packets are ordinary DatagramPackets. Multicast is UDP: unreliable, unordered, atomic per datagram. Everything from L13.5 applies, setLength trap included.

Only two operations are new. joinGroup(group) tells the local stack to accept packets addressed to that group and signals the local multicast router to start delivering the group down this branch. leaveGroup(group) withdraws both. You must join before you can receive — and you do not need to join to send. A sender that never wants the traffic simply constructs a MulticastSocket, addresses a DatagramPacket to the group, and calls send.

A single socket may join several groups; the incoming packet's address tells you which group it came from. Several sockets in one JVM may join the same group, and each gets a full copy.

TTL is the scope dial

Every IP packet carries a time-to-live, decremented by at least one at each router and discarded at zero. It exists to kill routing loops. Multicast repurposes it as a crude geographic limiter, and setTimeToLive(int) sets it for everything the socket sends:

  • 0 — never leaves the sending host.
  • 1 — the local subnet only. This is the default, and it is the right default: it means a careless program cannot flood anybody else's network.
  • 16 — roughly a campus.
  • 64 and up — progressively wider, up to 255 for no limit at all.

The mapping to geography is a convention, not a guarantee; the number counts routers, and how far a router is from you is nobody's fixed property. Modern designs prefer administrative scoping — confining traffic by choosing a 239.x.x.x address whose boundary the routers enforce — precisely because a hop count is a guess and a policy boundary is not.

Why it stops at the edge

Multicast needs every router on the path to be multicast-capable and configured to forward the group. Inside one organisation that is a decision an administrator makes once. Across the public internet it is not: most consumer ISPs deliberately do not enable multicast forwarding, so between two arbitrary hosts there is usually no multicast path at all, and your packets die at the first ordinary router.

The practical consequence is a design rule, not a disappointment. Multicast is a LAN and datacentre technology: service discovery, cluster membership, market-data fan-out, campus video. Streaming to the public internet is done with unicast and a content delivery network, which is multicast's fan-out idea rebuilt at the application layer where it does not need the routers' permission.

Worked example — a group sniffer and a group announcer

The sniffer. Resolve 239.1.2.3 to an InetAddress. Open new MulticastSocket(4446) — the port has to match what the senders use, since the group address selects the group and the port still selects the application. joinGroup(group). Then loop exactly as in L13.5: one 1,024-byte buffer, one DatagramPacket, receive, decode with getLength(), print the sender from getAddress(), and reset with setLength(buffer.length). On the way out, leaveGroup(group) and close.

The printed sender address is the interesting part: it is the unicast address of whichever host sent, never the group. The group is the destination, so packets from many different hosts arrive on one socket and you tell them apart exactly the way the UDP echo server did.

The announcer. No join at all. Construct a MulticastSocket() on an anonymous port, setTimeToLive(1) to keep the announcement on this subnet, build a DatagramPacket addressed to the same group and port 4446, and send. Run the sniffer on three machines on one switch and one send arrives at all three — and at none of the machines that did not join.

Swap the group for 192.168.1.50 and joinGroup throws an IOException before anything else can go wrong, because that address is not in 224.0.0.0/4. The group is not a convention layered on a normal address; it is the address range itself.

sendnoSsends onceG239.1.2.3R1joinedR2joinedR3joinedXnever joinedJoining, not addressing, decides who receives.
The sender addresses the group, never a receiver, and transmits once. Membership is what decides delivery: the fourth host is on the same network and is perfectly reachable, but because it never called joinGroup the network simply does not hand it the traffic.
NORMAL ~/memra/learn/comp-348/multicast-groups-and-ttl utf-8 LF