21 Java UDP Socket Programming

Dr M. Vijayalakshmi

    UDP communication

 

UDP (User Datagram Protocol) delivers independent packages whose arrival and the order of arrival is not guaranteed. Packets sent by UDP protocol are called as Datagrams. A DataGram is an independent, self-contained message sent over the network whose arrival, and content are not guaranteed.

 

Classes in Java that are supported to develop for UDP connection are DatagramPacket, DatagramSocket and MulticastSocket etc.

 

Datagram Sockets

 

DatagramSocket defines four public constructors. They are,

 

1.   DatagramSocket( ) throws SocketException

  • This constructor creates a DatagramSocket bound to any unused port on the local computer.

   2.  DatagramSocket(int port) throws SocketException

  • This constructor creates a DatagramSocket bound to the port specified by port.

    3. DatagramSocket(int port, InetAddress ipAddress) throws SocketExce ption

  • This constructor constructs a DatagramSocket bound to the specified port and InetAddress.

   4. DatagramSocket(SocketAddress address) throws SocketException

  • This constructor constructs a DatagramSocket bound to the specified SocketAddress.
  • SocketAddress is an abstract class that is implemented by the concrete class InetSocketAddress.

    Create UDP Socket

 

To develop UDP socket communication, the client uses a constructor that does not require a port number. This constructor just binds the DatagramSocket to any available local port. It doesn’t matter what port the client is connected to because the DatagramPackets will contain the addressing information. The server gets the port number from the DatagramPackets and send its response to that port.

 

 

Methods of Datagram Socket

 

DatagramSocket defines many methods. Two of the most important are send( ) and receive( ).

  • void send(DatagramPacket packet) throws IOException
  • void receive(DatagramPacket packet) throws IOException

    1. The send( ) method sends packet to the port specified by packet.

2. The receive() method waits for a packet to be received from the port specified by packet and returns the result.

 

DatagramPacket class

 

The Constructors of DatagramPacket are listed below,

 

1.  DatagramPacket(byte buf[], int offset, int length)

    This constructor constructs a DatagramPacket for receiving packets of length length, specifying an offset into the buffer.

2. DatagramPacket(byte buf[], int length)

    This constructor constructs a DatagramPacket for receiving packets of length length.

3. DatagramPacket(byte buf[], int offset, int length, InetAddress address, int port).

   This constructor constructs a datagram packet for sending packets of length length with offset offset to the specified port number on the specified host.

4. DatagramPacket(byte buf[], int offset, int length, SocketAddress address)

  This constructor constructs a datagram packet for sending packets of length length with offset offset to the specified port number on the specified host.

5. DatagramPacket(byte buf[], int length, InetAddress address, int port)

   This constructor constructs a datagram packet for sending packets of length length to the specified port number on the specified host.

6.DatagramPacket(byte buf[], int length, SocketAddress address)

   This constructor constructs a datagram packet for sending packets of length length to the specified port number on the specified host.

 

Methods of DatagramPacket

 

1.  void setAddress(InetAddress iaddr)

Sets the IP address of the machine to which this datagram is being sent.

2. InetAddress getAddress()

   Returns the IP address of the machine to  which this datagram is being sent or from which the datagram was received.

3. void setSocketAddress(SocketAddress address)

   Sets the SocketAddress (usually IP address + port number) of the remote host to which this datagram is being sent.

4. SocketAddress getSocketAddress()

   Gets the SocketAddress (usually IP address + port number) of the remote host that this packet is being sent to or is coming from.

5. void setPort(int iport)

    Sets the port number on the remote host to which this datagram is being sent.

6. int getPort()

   Returns the port number on the remote host to which this datagram is being sent or from which the datagram was received.

7. byte[] getData()

   Returns the data buffer.

8.int getOffset()

  Returns the offset of the data to be sent or the offset of the data received.

9.int getLength()

   Returns the length of the data to be sent or the length of the data received.

10. void setData(byte[] buf, int offset, int length)

      Set the data buffer for this packet.

11. void setData(byte[] buf)

     Set the data buffer for this packet.

12. void setLength(int length)

    Set the length for this packet.

 

Example of ChatUDP Server and ChatUDP Client

     An example is illustrated for chat client server communication with UDP sockets.

 

ChatUDP Server

 

A Datagram socket is created and binded with the port number 6000 on the localhost machine.A Datagram Packet ‘dp1’ is constructed to receive datagrams sent from the client. Once the datagram is received using the method receive(dp1), the byte data is obtained using dp1.getData() method. Then the bytes are converted to String and displayed on the screen.

 

Message from the user is again read as a String which is then converted to bytes using s.getBytes() method. A DatagramPacket ‘dp2’ is then constructed with the buffer data and sent to the specified port number extracted from the received datagram ‘dp1’using the method dp1.getPort() and to the specified host extracted from received datagram ‘dp1’ using the method dp1.getAddress(). This whole chat runs in a loop until the user enters a string ‘exit’.

      import java.io.*;

  import java.net.*; 

   public class ChatUDPServer1

       {

    public static void main(String args[]) throws Exception

{

DatagramSocket ds = new DatagramSocket(6000); byte[] b;

DatagramPacket dp1,dp2;

String s;

BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); b = new byte[1024];

do

{

dp1 = new DatagramPacket(b, b.length);

ds.receive(dp1);

b=dp1.getData();

/* Don’t use s=new String(b,0,0,b.length);—–is wrong. Use only dp1.getLength() */

//s=new String(b,0,0,dp1.getLength());

s = new String(b);

System.out.println(s);

if(s.equals(“exit”))

break;

s=br.readLine();

   b=s.getBytes();

   dp2 = new DatagramPacket(b, s.length(), dp1.getAddress(),dp1.getPort());

  ds.send(dp2); 

  }while(!s.equals(“exit”));

  }

  }

   

ChatUDPClient

 

A Datagram socket is created and binded with the available port number on the localhost machine. Message from the user is read as a string which is then converted to bytes using s.getBytes() method. A DatagramPacket ‘dp1’ is then constructed with the buffer data and sent to the specified port number 6000 and on the specified host given as local host where the server is running.

 

A Datagram Packet ‘dp2’ is constructed to receive datagrams sent from the server. Once the datagram is received using ds.receive(dp2) the byte data is obtained using dp2.getData() method. Then the bytes are converted to string and displayed on the screen. This whole chat runs in a loop until the user enters a string ‘exit’.

 

import java.io.*;

import java.net.*;

public class ChatUDPClient1

{

public static void main(String args[]) throws Exception

{

DatagramSocket ds = new DatagramSocket();

DatagramPacket dp1,dp2;

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

byte b[];

String s;

if(s.equals(“exit”))

break;

 /* To test whether the packet contains only the required data (i.e., not empty spaces)*/ /* Use    b=dp1.getData();

 System.out.println(new String(b,0,0,dp1.getLength()));

do

{

*/

s=br.readLine();

b=new byte[1024];

b=s.getBytes();

dp1=new DatagramPacket(b, s.length(), InetAddress.getByName(“localhost”), 6000); ds.send(dp1);

dp2=new DatagramPacket(b, b.length);

ds.receive(dp2);

b=dp2.getData();

s=new String(b);

System.out.println(s);

}while(!s.equals(“exit”));

}

}

    Output of ChatUDP Server & Client

 

The output of Chat UDP server and Chat UDP client is shown in Figure 23.1.

 

 

Figure: 23.1 Output of ChatUDP Server & ChatUDP Client

 

 

Multicast Communication

 

Multicasting sends data from one host to many different hosts, but not to everyone. The data goes only to clients that have expressed interest in the data by joining a particular multicast group. Multicast Sockets in Java uses the DatagramPacket class along with a new MulticastSocket class. The IETF has set aside addresses from 224.0.0.1 to 239.255.255.255 specifically for multicasting.

 

Multicast Sockets

 

Four Key Operations

 

The behavior of MulticastSocket is very similar to DatagramSocket’s. We can use a normal DatagramSocket to send and receive unicast and broadcast datagrams and to send multicast datagrams but in order to receive multicast datagrams, we need a MulticastSocket. The four key operations while performing multicast communication is listed below,

 

1.  Join a multicast group

2. Send data to the member of the group

3. Receive data from the group

4.  Leave the group 

     java.net.MulticastSocket

 

It is the subclass of java.net.DatagramSocket and constructed in the same way.

 

Some extra methods used here are:

 

1.  void joinGroup(InetAddress mcastGroup)

Enter the specifies group so that you can send or receive datagrams

2. void leaveGroup(InetAddress mcastGroup)

Leave a group that you previously joined

3. void setTimeToLive(int ttl)

Sets how far your datagrams will travel before routers ignore them

4. int getTimeToLive()

Get the default time-to-live for multicast packets sent out on the socket.

 

MulticastSender

 

The steps involved in sending datagrams through Multicast Socket are,

 

1.  Create the MulticastSocket.

2. Join the multicast group(s) (on startup).

3. Create the DatagramPacket.

4. Send the packet through the socket.

5. Leave the multicast group (on exit).

     Snippet code to demonstrate the above steps to send datagrams through Multicast socket.

 

InetAddress multicastGroup =  InetAddress.getByName(multicastGroupAddr);

MulticastSocket socket = new MulticastSocket();

socket.joinGroup(multicastGroup);

socket.setTimeToLive(5);

byte[] data = “This is the message”.getBytes();

DatagramPacket datagram = new DatagramPacket(data, data.length);

datagram.setAddress(multicastGroup);

datagram.setPort(1234);

socket.send(datagram);

socket.leaveGroup(multicastGroup);

 

MulticastReceiver

 

The steps involved in receiving datagrams through Multicast Socket are,

 

1. Create a multicast socket on an agreed port.

2. Join the multicast group (on startup).

3. Create an empty datagram.

4. Wait for datagram to be delivered on the socket.

5. Unpack and use the datagram.

6. Leave the multicast group (on exit).

    Snippet code to demonstrate the above steps to receive datagrams through Multicast socket.

     InetAddress multicastGroup =  InetAddress.getByName(multicastGroupAddr);

MulticastSocket socket = new MulticastSocket(1234);

socket.joinGroup(multicastGroup);

byte[] data = new byte[1000];

DatagramPacket packet = new DatagramPacket(data, data.length); socket.receive(packet);

String message = new String(packet.getData(), 0, packet.getLength()); socket.leaveGroup(multicastGroup);

 

Example of MulticastGroup

 

Initially a multicast socket is created on an agreed port. To receive the multicast messages one has to join the multicast group (on startup) using the method ds.joinGroup(group). An empty datagram is then created to receive the message. Then the client waits for datagram to be delivered on the socket. The datagram is then unpacked and used. Finally it leaves the multicast group on exit.

 

import java.io.*;

import java.net.*;

public class MulticastGroup

{

public static void main(String args[])

{

InetAddress group = null;

int port = 0;

try

{

group = InetAddress.getByName(args[0]);

port = Integer.parseInt(args[1]);

}

catch( Exce ption e)

{

System.err.println(“usage”);

System.exit(1);

}

MulticastSocket ds = null;

try {

ds = new MulticastSocket(port);

ds.joinGroup(group);

byte[] buffer = new byte[8192];

//   while(true)

//    {

DatagramPacket dp = new DatagramPacket(buffer, buffer.length); ds.receive(dp);

String s = new String(dp.getData());

System.out.println(s);

//   }

catch(IOException e)

{

System.err.println(e);

}

finally

{

if(ds != null)

{

try{ ds.leaveGroup(group);

ds.close();

}

catch(IOException e){}

}

}

}

}

   

Example of Multicast Sender

 

Initially the Multicast IP address 228.5.6.7 and port number 8759 are given as command line arguments. Datagram packet is constructed to the given IP address and port number. MulticastSocket is then created using the constructor of the class. The Multicast sender is joined in the the multicast group(s) using the method ms.joinGroup(group). The created DatagramPacket is then sent through the socket. Finally it leaves the multicast group on exit.

       import java.io.*;

   import java.net.*;

     public class MulticastSender

{

public static void main(String[] args)

{

InetAddress group = null;

int port = 0;

try

{

group = InetAddress.getByName(args[0]);

port = Integer.parseInt(args[1]);

}

catch( Exception e)

{

System.err.println(e);

System.exit(1);

}

byte[] data = “here multicast data”.getBytes();

DatagramPacket dp = new DatagramPacket(data, data.length, group, port); try{

MulticastSocket ms = new MulticastSocket();

ms.joinGroup(group);

ms.send(dp);

ms.leaveGroup(group);

ms.close();

}

catch(SocketException se)

{

System.err.println(se);

}

catch(IOException e)

{

System.err.println(e);

}  }  }

 

Output of Multicast Sockets

 

The output of Multicast communication is shown in Figure 23.2. There are four entities, one act as a multicast sender and the other three are multicast clients who receive the message from the sender. All the four entities has to join the multicast group for communication.

Figure 23.2 Multicast communication

 

TCP Socket Options

 

Several methods can be used to set various socket options. Most of the time the defaults are fine.

 

1. public void setTcpNoDelay(boolean on) throws SocketException

2. public boolean getTcpNoDelay() throws SocketException

    Disable Nagle’s algorithm. Valid for (client) Sockets.

3. public void setSoLinger(boolean on, int val) throws SocketException

4. public int getSoLinger() throws SocketException

    Specify a linger-on-close timeout. Valid for (client) Sockets.

5. public synchronized void setSoTimeout(int timeout) throws SocketException

6. public synchronized int getSoTimeout() throws SocketException

    Specify a timeout on blocking socket operations. Valid for all sockets like Socket, ServerSocket, DatagramSocket.

 

Summary

 

This module explains about UDP socket communication in Java. This module gives an idea about DatagramPacket and DatagramSocket classes to build UDP communication. This module also explores about Multicasting with UDP sockets.

 

References

  1. download.java.net/jdk7/archive/b123/docs/api/java/net/DatagramPacket.html
  2. https://www.cs.auckland.ac.nz/~jmor159/364/ppt/AJavaNetworking.ppt

   Web Links

  • Herbert Schildt, ” Java: The Complete Reference”, 9th Edition, Mcgraw-Hill, 2014.
  • https://www.cs.auckland.ac.nz/~jmor159/364/ppt/AJavaNetworking.ppt
  • download.java.net/jdk7/archive/b123/docs/api/java/net/DatagramPacket.html