Sunday, January 19, 2014

Unicast, Multicast and Broadcast

These correspond to three types of sockets in Java. ServerSocket is perhaps the most commonly used one as most people are somewhat familiar with TCP ("Indeed, TCP works with only unicast addresses, although UDP and raw IP support other paradigms" [1]). But there are also DatagramSockets and MulticastSockets.

First, a quick overview [1]:

Unicasting is where a process is talking to exactly one other process.

Broadcasting sends a datagram that all hosts on the attached subnet receive. The disadvantage is that every host on the subnet must process the datagram ... even if the host is not participating in the application.

A multicast datagram is sent to some hosts. Datagrams should be received only by those interfaces on hosts running applications wishing to participate in the multicast group.

(TCP is an example of a unicast protocol. ARP and DHCP use broadcasting or multicasting [1])

Sockets corresponding to DatagramSocket look like this in netstat:

mds@gbl04224[dev]:~> netstat -nap 2>/dev/null | grep 8888 
udp        0      0 :::8888                 :::*                                29525/java 

or

mds@gbl04224[dev]:~> netstat -nap 2>/dev/null | grep 8888 
udp        0      0 0.0.0.0:8888            0.0.0.0:*                           32331/java 

if they're using IPv4.

This is what you'd see if you ran:

        DatagramSocket datagramSocket = new DatagramSocket(null); 
        datagramSocket.bind(new InetSocketAddress(8888)); 

using  -Djava.net.preferIPv6Stack=true and -Djava.net.preferIPv4Stack=true respectively.

Multicast sockets look the same. That is, if you run:

        InetAddress     group = InetAddress.getByName("228.5.6.7"); 
        MulticastSocket multicastSocket = new MulticastSocket(6789); 
        multicastSocket.joinGroup(group); 

it produces the same kind of output from netstat, although note: multiple processes can use the same multicast socket:

mds@gbl04224[dev]:~> netstat -nap 2>/dev/null | grep 6789 
udp        0      0 :::6789                 :::*                                23912/java 
udp        0      0 :::6789                 :::*                                23824/java 

but not the same datagram socket:

mds@gbl04224[dev]:/opt/mds/storage/Phill/Java> java -cp . com.phenry.io.Multicast 
Exception in thread "main" java.net.BindException: Address already in use 
        at java.net.PlainDatagramSocketImpl.bind0(Native Method) 
        at java.net.PlainDatagramSocketImpl.bind(PlainDatagramSocketImpl.java:82) 
        at java.net.DatagramSocket.bind(DatagramSocket.java:368) 
        at com.phenry.io.Multicast.bindDatagramSocket(Multicast.java:21) 
        at com.phenry.io.Multicast.main(Multicast.java:14) 

Run netstat with the -g flag to see group membership. Linux also tells you how many listeners there are. For instance, running the multicast code above yields:

$ netstat -g 
IPv6/IPv4 Group Memberships
Interface       RefCnt Group
--------------- ------ ---------------------
lo              1      all-systems.mcast.net
eth0            1      228.5.6.7

Running it a second time with the first process still running gives:

$ netstat -g
IPv6/IPv4 Group Memberships
Interface       RefCnt Group
--------------- ------ ---------------------
lo              1      all-systems.mcast.net
eth0            2      228.5.6.7


[1] Unix Network Programming, Stevens et al

No comments:

Post a Comment