Home / Programming / Code Snippets / Java Snips / Multicast Using Java Sockets
socket pogram

Multicast Using Java Sockets

Java Socket APIs enable network communication where client-server communication can be established in three ways: one-to-one communication (client-server), one-to-all communication (broadcast), and one-to-many communication (multicast).

 

Basics: IPv4 uses 32-bit addressing and can be supported about 4.3 billion devices, IPv6 uses 64-bit addressing that can support about 3.4e104 devices! However, IPv4 is still is in use and thriving; therefore, we’ll restrict our discussion only to IPv4.

 

IPv4 address format example: 192.168.17.14 (Class C)

1st Octet Range 2nd Octet Range 3rd Octet range 4th Octet Range
Range (0-255) (0-255) (0-255) (0-255)

 

IP ranges: Class A, Class B, Class C, Class D, and Class E

Class First Octet Range Network (N), Host (H) Subnet Mask No. of Networks Hosts per Network
A 1-126 N.H.H.H. 255.0.0.0 126 16777214
B 128-191 N.N.H.H. 255.255.0.0 16382 65534
C 192-223 N.N.N.H. 255.255.255.0 2097150 254
D 224-239 Used for Multicasting.
E 240-254 Experimental; reserved for research purposes.

IP Address 127.x.x.x is reserved as a loopback address, termed localhost. IP Address 255.255.255.255 is used to broadcast to all hosts in the local area network. And, there are a few private IP addresses (not relevant at the point of our discussion).

 

A Quick Example

The MulticastSocket class defined in the java.net package represents a multicast socket. Once a MulticastSocket object is created, the joinGroup() method is invoked to make it one of the members to receive a multicast message. Note that a multicast IP address is defined in the range of 224.0.0.0 to 239.255.255.255. Following is the IP multicast address ranges and uses.

Start Address End Address Uses
224.0.0.0 224.0.0.255 Reserved for special “well known” multicast addresses
224.0.1.0 238.255.255.255 Globally scoped (Internet-wide) multicast address
239.0.0.0 239.255.255.255 Administratively scoped (local) multicast addresses

Source: http://www.tcpipguide.com/free/t_IPMulticastAddressing.htm

 

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class UDPMulticastClient implements Runnable {

   public static void main(String[] args) {
      Thread t=new Thread(new UDPMulticastClient());
      t.start();
   }

   public void receiveUDPMessage(String ip, int port) throws
         IOException {
      byte[] buffer=new byte[1024];
      MulticastSocket socket=new MulticastSocket(4321);
      InetAddress group=InetAddress.getByName("230.0.0.0");
      socket.joinGroup(group);
      while(true){
         System.out.println("Waiting for multicast message...");
         DatagramPacket packet=new DatagramPacket(buffer,
            buffer.length);
         socket.receive(packet);
         String msg=new String(packet.getData(),
         packet.getOffset(),packet.getLength());
         System.out.println("[Multicast UDP message received]
            >> "+msg);
         if("OK".equals(msg)) {
            System.out.println("No more message. Exiting : "+msg);
            break;
         }
      }
      socket.leaveGroup(group);
      socket.close();
   }

   @Override
   public void run(){
   try {
      receiveUDPMessage("230.0.0.0", 4321);
   }catch(IOException ex){
      ex.printStackTrace();
   }
}

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPMulticastServer {

   public static void sendUDPMessage(String message,
   String ipAddress, int port) throws IOException {
      DatagramSocket socket = new DatagramSocket();
      InetAddress group = InetAddress.getByName(ipAddress);
      byte[] msg = message.getBytes();
      DatagramPacket packet = new DatagramPacket(msg, msg.length,
         group, port);
      socket.send(packet);
      socket.close();
   }

   public static void main(String[] args) throws IOException {
      sendUDPMessage("This is a multicast messge", "230.0.0.0",
         4321);
      sendUDPMessage("This is the second multicast messge",
         "230.0.0.0", 4321);
      sendUDPMessage("This is the third multicast messge",
         "230.0.0.0", 4321);
      sendUDPMessage("OK", "230.0.0.0", 4321);
   }
}

Multicasting Through Datagram Channels

Java supports multicasting through datagram channels through the class called DatagramChanneldefined in the java.nio.channels package. A datagram channel that wants to receive multicast messages is joined to a multicast group. In this way, it becomes a member of the group to receive multicast messages. Once the connection is established, the datagram channel remains connected until it is disconnected or closed. Therefore, we can check the status of a datagram channel by invoking the isConnected() method, which return a Boolean true if the connection is open and false otherwise.

Here is a quick example to illustrate how to use datagram channels in multicasting.

A Quick Example

Using datagram channels has some additional advantages, such as we can opt to receive multicast datagrams only from selected sources and block others. For example, we can use the block(InterAddress) method from the MembershipKey class to block a multicast message source. There is a method, called unblock(InetAddress), that unlocks the same. Here, we’ll implement the simple multicast message sending and receiving scenario. Refer to the Java API documentation for additional API information.

 

package org.mano.example;
import java.io.IOException;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.MembershipKey;

public class MulticastReceiver {
   private static final String MULTICAST_INTERFACE = "eth0";
   private static final int MULTICAST_PORT = 4321;
   private static final String MULTICAST_IP = "230.0.0.0";
   private String receiveMessage(String ip, String iface, int port)
         throws IOException {
      DatagramChannel datagramChannel = DatagramChannel
         .open(StandardProtocolFamily.INET);
      NetworkInterface networkInterface = NetworkInterface
         .getByName(iface);
      datagramChannel.setOption(StandardSocketOptions
         .SO_REUSEADDR, true);
      datagramChannel.bind(new InetSocketAddress(port));
      datagramChannel.setOption(StandardSocketOptions
         .IP_MULTICAST_IF, networkInterface);
      InetAddress inetAddress = InetAddress.getByName(ip);
      MembershipKey membershipKey = datagramChannel.join
         (inetAddress, networkInterface);
      System.out.println("Waiting for the message...");
      ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
      datagramChannel.receive(byteBuffer);
      byteBuffer.flip();
      byte[] bytes = new byte[byteBuffer.limit()];
      byteBuffer.get(bytes, 0, byteBuffer.limit());
      membershipKey.drop();
      return new String(bytes);
   }
   public static void main(String[] args) throws IOException {
      MulticastReceiver mr = new MulticastReceiver();
      System.out.println("Message received : "
         + mr.receiveMessage(MULTICAST_IP,
         MULTICAST_INTERFACE, MULTICAST_PORT));
   }
}


package org.mano.example;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
public class MulticastPublisher {
   private static final String MULTICAST_INTERFACE = "eth0";
   private static final int MULTICAST_PORT = 4321;
   private static final String MULTICAST_IP = "230.0.0.0";
   public void sendMessage(String ip, String iface, int port,
         String message) throws IOException {
      DatagramChannel datagramChannel=DatagramChannel.open();
      datagramChannel.bind(null);
      NetworkInterface networkInterface=NetworkInterface
         .getByName(iface);
      datagramChannel.setOption(StandardSocketOptions
         .IP_MULTICAST_IF,networkInterface);
      ByteBuffer byteBuffer=ByteBuffer.wrap
         (message.getBytes());
      InetSocketAddress inetSocketAddress=new
         InetSocketAddress(ip,port);
      datagramChannel.send(byteBuffer,inetSocketAddress);
   }
   public static void main(String[] args) throws IOException {
      MulticastPublisher mp=new MulticastPublisher();
      mp.sendMessage(MULTICAST_IP,MULTICAST_INTERFACE,
         MULTICAST_PORT,"Hi there!");
   }
}

Conclusion

Multicasting through Java is a part of the Java network programming paradigm. The communication between two remote hosts actually goes through several layers as defined the reference model or the TCP/IP model. The underlying principle of communication is complex. But, from the point of view of Java programming, it is made simple with the APIs supplied by the network library. Although UDP is termed as a not so reliable protocol, in practice it is not that unreliable, either. And, TCP is resource hungry. Therefore, in most cases, UDP seems to be a better alternative. TCP can do almost everything that UDP can do—except that multicasting and broadcasting is possible only with UDP.

 

This post appeared in https://www.developer.com

About revive

Leave a Reply

Leave a Reply

  Subscribe  
Notify of
%d bloggers like this: