Datagrams

The two important protocols in the transport layer are the User Datagram Protocol (UDP) and the Transmission Control Protocol (TCP). UDP is the connectionless protocol while TCP is the connection-oriented protocol.

In a connectionless protocol, a message is broken into sequentially numbered packets called datagrams. Each datagram is provided with the address of the receiver. Thus, the route traveled by datagram 42 may be different that the route traveled by datagram 39. This means 42 may arrive before 39. It is the responsibility of the receiver to arrange the datagrams in the proper order.

UDP

The sender:

1. Creates a datagram socket connected to the receiver
2. Creates a datagram packet containing a message
3. Sends the packet
4. closes the socket

The receiver:

1. Creates a datagram socket bound to a specific port
2. Creates a datagram packet containing a buffer
3. Receives a packet from the sender
4. closes the socket

Relevant Java Classes

class java.net.DatagramSocket;
class java.net.DatagramPacket;
class java.net.InetAddress;

UDP in Java

The sender:

1. DatagramSocket socket = new DatagramSocket();
2. DatagramPacket packet = new DatagramPacket(
      buffer,
      buffer.length,
      receiverHost,
      receiverPort);
3. socket.send(datagram);
4. socket.close();

The receiver:

1. DatagramSocket socket = new DatagramSocket(port);
2. DatagramPacker packet =
      new DatagramPacket(buffer, buffer.length);
3. socket.receive(datagram); // blocking receive
4. socket.close();

Notes:

Valid port numbers are 0 - 65535.
Ports 0 - 1023 are reserved for wel known services.

A Simple UDP Framework

MyDatagram.java

import java.net.*;
import java.io.*;

public class MyDatagramSocket extends DatagramSocket {
   protected static final int CAP = 80; // receive's buffer capacity
   DatagramPacket packet; // packet received
   public MyDatagramSocket(int port) throws SocketException {
      super(port);
   }
   public MyDatagramSocket() throws SocketException {
      this(5555);
   }
   public String receive() {
      byte[] buffer = new byte[CAP];
      try {
         packet = new DatagramPacket(buffer, CAP);
         super.receive(packet);
      } catch(IOException e) {
         System.err.println(e.getMessage());
      }
      return new String(buffer);
   }
   public void send(InetAddress hostIP, int port, String msg) {
      try {
         byte[] buffer = msg.getBytes();
         DatagramPacket packet =
            new DatagramPacket(buffer, buffer.length, hostIP, port);
         super.send(packet);
      } catch(IOException e) {
         System.err.println(e.getMessage());
      }
   }
   public void send(String host, int port, String msg) {
      try {
         InetAddress hostIP = InetAddress.getByName(host);
         send(hostIP, port, msg);
      } catch(IOException e) {
         System.err.println(e.getMessage());
      }
   }
   public void send(int port, String msg) {
      send("localhost", port, msg);
   }

   public void sendResponse(String msg) {
      if (packet != null) {
         send(packet.getAddress(), packet.getPort(), msg);
      }
   }
}

Datagram Sender

public class UDPSender {

   public static void main(String[] args) {
      int port = 4444;
      String host = "localhost";
      String msg = "greetings";
      if (1 <= args.length) {
         msg = args[0];
      }
      if (2 <= args.length) {
         port = Integer.parseInt(args[1]);
      }
      if (3 <= args.length) {
         host = args[2];
      }
      try {
         MyDatagramSocket sock = new MyDatagramSocket();
         System.out.println("sending: " + msg);
         sock.send(host, port, msg);
         msg = sock.receive();
         System.out.println("received: " + msg);
         sock.close();
      } catch(Exception e) {
         System.err.println(e.getMessage());
      }
   }

}

UDPServer.java

public class UDPServer {
   private MyDatagramSocket sock;
   public UDPServer(int port) {
      try {
         sock = new MyDatagramSocket(port);
      } catch (Exception e) {
         System.err.println(e.getMessage());
      }
   }
   protected String response(String msg) {
      return "echo: " + msg;
   }
   public void controlLoop() {
      System.out.println("UDP Server is listening ... ");
      while(true) {
         String msg = sock.receive();
         System.out.println("message received: " + msg);
         if (msg.trim().equals("quit")) break;
         msg = response(msg);
         System.out.println("message sent: " + msg);
         sock.sendResponse(msg);
      }
      sock.send("bye");
      sock.close();
      System.out.println("bye");
   }

   public static void main(String[] args) {
      int port = 4444;
      if (1 <= args.length) {
         port = Integer.parseInt(args[0]);
      }
      UDPServer server = new UDPServer(port);
      server.controlLoop();
   }

}

Program Output

Sender

Receiver