Header javaperspective.com
JavaPerspective.com  >   Intermediate Tutorials  >   4. Networking  >   4.4. UDP servers and clients

4.4. UDP servers and clients
Last updated: 1 February 2013.

This tutorial will show you how to implement a basic UDP server and a client for that server. The server will simply deliver a string representing the current date and time to remote clients.


4.4.1. How to implement a UDP server

The core classes to use when implementing a UDP server are DatagramSocket and DatagramPacket. A DatagramSocket object represents an endpoint defined by an IP address, a transport protocol (UDP in this case) and a port number.

A DatagramSocket object can send and receive DatagramPacket objects across a network. However, the packets may be lost or arrive out of order to the recipient. Basically, a UDP server is a thread that calls the method receive(DatagramPacket p) provided by the class DatagramSocket in an infinite loop. Whenever a packet is received, the server sends back a response to the client by calling the method send(DatagramPacket p).

In the following example, the class UdpServer listens to requests from clients on the port number 7777. If a client sends the string GET, the server sends back a string representing the current date and time:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Date;

public final class UdpServer extends Thread {

   
private DatagramSocket datagramSocket;
   
private int portNumber = 7777;


   
public UdpServer() throws SocketException {
         
setName("UdpServer");
         
         
// create a DatagramSocket instance and bind it to the specified port number
         
datagramSocket = new DatagramSocket(portNumber);
   
}


   
public void run(){
         
try{
               
while (! isInterrupted()) {
                     
                     
// Build a DatagramPacket object to receive a packet
                     
byte[] buffer = new byte[256];
                      DatagramPacket requestPacket =
new DatagramPacket(buffer, buffer.length);
                     
                     
// Receive a packet from a client. The method "receive" blocks until a packet arrives
                     
datagramSocket.receive(requestPacket);
                     
                     
// Get the string contained in the received packet
                     
String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
                     
                     
if(request.equals("GET")){
                           
// Build a DatagramPacket object to send a response packet to the client
                           
String response = new Date().toString();
                            buffer = response.getBytes
();
                            DatagramPacket responsePacket =
new DatagramPacket(buffer, buffer.length, requestPacket.getAddress(), requestPacket.getPort());
                           
                           
// Send the packet to the client
                           
datagramSocket.send(responsePacket);
                     
}   
                }
          }
         
catch(IOException e){
               
e.printStackTrace();
         
}
         
finally{
               
// close the DatagramSocket instance before termination
               
datagramSocket.close();
         
}
    }
}

Unlike the TCP server that you have seen in the previous tutorial, the UDP server shown above is not multithreaded. Instead, packets are handled by the same thread as they arrive since there are no connections to handle at all with the clients.

As you can see, the DatagramPacket object named requestPacket wraps an array of bytes which stores the data received from a client. If the received data is larger than the size of that array, then the received data is truncated. The class UdpServerStarter shown below contains a main method that creates and starts an instance of the class UdpServer:

import java.net.SocketException;

public final class UdpServerStarter {

   
public static void main(String[] args){
         
try{
               
UdpServer udpServer = new UdpServer();
                udpServer.start
();
         
}
         
catch(SocketException e){
               
e.printStackTrace();
         
}
    }
}


4.4.2. How to implement a UDP client

To implement a UDP client, you need to create an instance of the class DatagramSocket with the default constructor. That constructor builds a datagram socket and binds it to any available local port number. Next, just call the method send(DatagramPacket p) provided by the class DatagramSocket to send to the server a DatagramPacket object that wraps the request in an array of bytes.

Assuming that the server and the client are running on the same computer, the class UdpClient shown below contains a main method and a method named process which sends a GET request to a server that is running locally on the port number 7777. After the request has been sent, the client waits for the response from the server by calling the method receive(DatagramPacket p). To finish, the client closes the DatagramSocket object:

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

public final class UdpClient {

   
private void process() {
         
DatagramSocket datagramSocket = null;
         
         
try{
               
// Build a DatagramSocket and bind it to any available local port number
               
datagramSocket = new DatagramSocket();

               
// Build a DatagramPacket object to send a request packet to the server (the server is running locally)
               
String request = "GET";
               
byte[] buffer = request.getBytes();
                InetAddress serverAddress = InetAddress.getByName
("localhost");
                DatagramPacket requestPacket =
new DatagramPacket(buffer, buffer.length, serverAddress, 7777);

               
// Send the packet to the server
               
datagramSocket.send(requestPacket);

               
// Receive the response packet from the server
               
buffer = new byte[256];
                DatagramPacket responsePacket =
new DatagramPacket(buffer, buffer.length);
                datagramSocket.receive
(responsePacket);

               
// Get the string contained in the received packet
               
String received = new String(responsePacket.getData(), 0, responsePacket.getLength());

               
// Display the received string
               
System.out.println(received);
         
}
         
catch(IOException e){
               
e.printStackTrace();
         
}
         
finally{
               
// Close the DatagramSocket
               
if(datagramSocket != null)
                     
datagramSocket.close();
         
}
    }

   
public static void main(String[] args){
         
new UdpClient().process();
   
}
}

Note that the method receive(DatagramPacket p) blocks until the response from the server arrives. Since UDP is not reliable, the response sent by the server may be lost. To avoid blocking the client forever, you can call the method setSoTimeout(int timeout) to specify the maximum amount of time that the client must wait for the server's response. If the timeout expires while the client is blocked, a SocketTimeoutException is thrown. The method setSoTimeout(int timeout) must be called before the call to the method receive(DatagramPacket p).

The server must be started before the client. If you run the client, the current date will be displayed.


You are here :  JavaPerspective.com  >   Intermediate Tutorials  >   4. Networking  >   4.4. UDP servers and clients
Next tutorial :  JavaPerspective.com  >   Intermediate Tutorials  >   5. Graphical User Interfaces

Copyright © 2013. JavaPerspective.com. All rights reserved.  ( Terms | Contact | About ) 
Java is a trademark of Oracle Corporation
Image 1 Image 2 Image 3 Image 4 Image 5 Image 6 Image 7