Architecture & DesignSocket Programming: UDP Client/Server Application

Socket Programming: UDP Client/Server Application

TCP (Transmission Control Protocol) and UDP (User Datagram Protocol) are the only two protocols supported by Java that run on top of IP (Internet Protocol), and application layer protocols are built on top of these two. The basic difference between the protocols is that TCP is connection oriented and UDP is connectionless. Besides these two, there is another commonly used protocol, named ICMP (Internet Control Message Protocol). The common use of ICMP is the ping program. ICMP is not supported by Java because it uses raw IP datagrams to relay messages between hosts. Java, however, has a provision to implement them with the help of native code. Socket programmers should at least skim over the conceptual bases of the TCP/IP protocol stack before delving into network programming. The article tries to provide some key information with a focus on building an UDP client/server application in Java.

An Overview of UDP and TCP

TCP is a connection-oriented protocol layered on the top of IP of the TCP/IP stack with the ability to acknowledge receipt of packets at both ends. Acknowledgement ensures that the lost/corrupt packets can be retransmitted upon request. It also maintains a sequence in the sense that packets can be put back in the same order at the receiving end as they were transmitted. Although everything seems fair and advantageous at first look, it is also its weakness on occasion, because maintaining a guaranteed data transmission carries a fair amount of overhead (the header size of TCP packet is 20 bit whereas UDP header is 8 bit). In a situation where the order of the data is not that important or say, loss of a few packets does not matter to the verge of completely corrupting the data, TCP can be a real bottleneck. UDP is an unreliable connectionless protocol that neither guarantees that the packets will ever reach the destination nor that they will arrive in the same order they were sent. But, it works and surprisingly reaches the destination, without the slightest aura of “guarantee” or “reliability.” TCP can be best suited for file transfer or the like where loss of bits is unacceptable. UDP, on the other hand, is best suited where a little loss in the transmission bits does not matter. For example, a few lost bits in video or audio signals are less severe without much quality degradation. Further, error correction in UDP can be built into data streams at the application level to account for missing information. So, UDP is not a total loss, after all.

Socket Programming Jargon

Following are a few socket programming jargons. They appear confusing at the beginning. These are not definitions; rather, they are a hint to intuitive understanding. A pure definition can be obtained from any standard text.

  • IP Address (Who): Every machine in the network has an IP address. This is a number of the format of something like 192.168.0.12 that uniquely identifies a host. This number gives information about whom to connect. The loopback address (denoted by 127.0.0.1) refers to oneself (same machine).
  • Port(Where): If we know whom to connect, the port defines where to connect. It is denoted by a number ranging from 1 to 65,535. Each port provides a significant service. For example, HTTP service usually runs on port 80. When programming, care should be taken to allot a port that collides with already allocated ports.
  • Socket (How): Socket represents the connection between two hosts and defines how to connect.

So, if you put all three together, Socket may be viewed as a link that is hooked to the Port of the IP address of the hosts where TCP or UDP define the rules of the game.

A Quick Example of Client/Server Interaction with UDP

A TCP connection is like telephone calls where we dial up to connect to the person with whom we want to communicate. The connection remains intact throughout the communication process even if we are not sending any signals. UDP, on the other hand, is more like mail carried through the postal service that assumes they may arrive out of sequence, lost in transit, or duplicate datagrams were detected at the receiving end.

In the following program, the user sends a message with the help of the Client application. The message is converted into a byte array before capsuling in a datagram packet. The Server receives the packet and echoes back in a similar manner.

UDP Server Program

package udpclientserverapp;

import java.awt.Dimension;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class Server extends JFrame {

   private final JTextArea msgArea = new JTextArea();
   private DatagramSocket socket;

   public Server() 
      super("Message Server");
      super.add(new JScrollPane(msgArea));
      super.setSize(new Dimension(450, 350));
      super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      super.setVisible(true);
      msgArea.setEditable(false);

      try {
         socket = new DatagramSocket(12345);

      } catch (SocketException ex) {
         System.exit(1);
      }
   }

   public void readyToReceivPacket() {
      while (true) {
         try {
            byte buffer[] = new byte[128];
            DatagramPacket packet =
               new DatagramPacket(buffer, buffer.length);
            socket.receive(packet);
            showMsg("nHost: " + packet.getAddress()
                    + "nPort: " + packet.getPort()
                    + "nLength: " + packet.getLength()
                    + "nData: "
                    + new String(packet.getData()));
            sendPacket(packet);
         } catch (IOException ex) {
            showMsg(ex.getMessage());
         }
      }
   }

   public void sendPacket(DatagramPacket packetReceived) {
      showMsg("nEcho to client...");
      try {
         DatagramPacket packet =
            new DatagramPacket(packetReceived.getData(),
            packetReceived.getLength(),
            packetReceived.getAddress(),
            packetReceived.getPort());
         socket.send(packet);
         showMsg("nMessage sent");
      } catch (IOException ex) {

      }
   }

   public void showMsg(final String msg) {
      SwingUtilities.invokeLater(() -> {
         msgArea.append(msg);
      });
   }

}



package udpclientserverapp;

public class StartServer {

   public static void main(String[] args) {
      Server server=new Server();
      server.readyToReceivPacket();
   }
}

UDP Client Program

package udpclientserverapp;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;


public class Client extends JFrame{
   private final JTextField msgField=new JTextField();
   private final JTextArea msgArea=new JTextArea();
   private DatagramSocket socket;

   public Client(){
      super("UDP Client");
      super.add(msgField, BorderLayout.NORTH);
      super.add(new JScrollPane(msgArea),
         BorderLayout.CENTER);
      super.setSize(new Dimension(450,350));
      super.setVisible(true);
      super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      msgArea.setEditable(false);

      try{
         socket=new DatagramSocket();
      }catch(SocketException ex){
         System.exit(1);
      }

      msgField.addActionListener((ActionEvent evt) -> {
         try{
            String msg=evt.getActionCommand();
            showMsg("nSendng message packet: "+msg);
            byte buff[]=msg.getBytes();
            DatagramPacket packetSend=
               new DatagramPacket(buff, buff.length,
               InetAddress.getLocalHost(), 12345);
            socket.send(packetSend);
            showMsg("nPacket sent");
         }catch(IOException ex){
            showMsg(ex.getMessage());
         }
      });

   }


   public void readyToReceivPacket(){
      while(true){
         try{
            byte buff[]=new byte[128];
            DatagramPacket packet=
               new DatagramPacket(buff,buff.length);
            socket.receive(packet);
            showMsg("nHost: " + packet.getAddress()
                    + "nPort: " + packet.getPort()
                    + "nLength: " + packet.getLength()
                    + "nData: "
                    + new String(packet.getData()));

         }catch(IOException ex){
            showMsg(ex.getMessage());
         }
      }
   }

   public void showMsg(final String msg) {
      SwingUtilities.invokeLater(() -> {
         msgArea.append(msg);
      });
   }

}

package udpclientserverapp;

public class StartClient {
   public static void main(String[] args) {
      Client client=new Client();
      client.readyToReceivPacket();
   }
}

Conclusion

Socket programming is used mainly to handle low-level network applications in Java. The java.net package provides the required library to quickly and easily write programs that accomplish many common networking tasks, such as DNS lookup, web browsing, handling POP, IMAP, SMTP, and so forth. TCP and UDP mainly provide the means to communicate between hosts through stream sockets and datagram sockets, respectively.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories