This Tech Tip reprinted with permission by

It's often the case that when someone shows some network programming that uses the standard J2SE libraries, the code is for the sockets-based model using the Transmission Control Protocol/Internet Protocol (TCP/IP). TCP/IP is used for internet communication tasks such as sending email through Simple Mail Transfer Protocol (SMTP), surfing the World Wide Web through Hypertext Transfer Protocol (HTTP), and browsing through newsgroups through Network News Transfer Protocol (NNTP). What TCP/IP guarantees is delivery of the communication.

In brief, the IP part of TCP/IP moves packets of data from node to node. The TCP part wraps source and destination addresses as well as ports with sequencing information and content. When a set of packets from a source address arrives at the destination, the destination host can resequence the packets into their original order such that the receiver can read the data in the original order it was sent.

If you're a user of classes such as Socket and URL, TCP/IP takes care of many of the details regarding communication. For example, TCP/IP determines which offset in the header to store the sequence and acknowledgment numbers for the TCP packet. In addition, encapsulating the TCP packet is something called an IP datagram packet. The packaging of datagrams when doing TCP/IP-based programming is also done for you.

But there might be cases where TCP/IP provides more than what you need. For example, what if you don't need to guarantee the delivery of the communication, or you don't want the delay introduced with retransmission of packets, or you don't need the data to be read in the original order it was sent? In these cases, you can use an alternative to TCP/IP called User Datagram Protocol (UDP). When working with UDP, you still send packets over the IP protocol, but there is no guarantee of delivery or order. Why might delivery not be important? Imagine creating a program that all machines in an office must run. Every few seconds each machine sends an "I'm alive" message to a central server. Does it matter if an "I'm alive" message is lost? The answer is typically no. There is nothing that the sender of the message can do besides resend the message, and it's going to send the same message in a few seconds anyway. Similarly, does it matter if the messages don't arrive in the exact order? Again, for this type of message: no, it doesn't matter. Do you really care if the 10:05 message arrives at 10:10? Not really. Of course, for high-end stock trading systems you don't want to lose pricing information, but for a low-priority stock ticker, does it really matter if you miss a price change? When it's time to make that stock trade, you will need to check again anyway. Actually, using TCP could be detrimental if missing packets get resent for realtime data. Timely, rather than orderly and reliable delivery, is more important in the realtime case.

UDP programming involves the DatagramPacket and DatagramSocket classes of the package. The DatagramPacket contains the information to send, including the identification of where to send that data. The DatagramSocket is used to send and receive packets.

The DatagramPacket class includes six constructors:

  • DatagramPacket(byte[] buf, int length, InetAddress address, int port)
  • DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
  • DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)
  • DatagramPacket(byte[] buf, int length, SocketAddress address)
  • DatagramPacket(byte[] buf, int length)
  • DatagramPacket(byte[] buf, int offset, int length)

Notice that the list of constructors is organized into three pairs. The first two pairs of constructors are used to create a packet for sending. The constructors in the first pair use an InetAddress for the destination address. The constructors in the second pair use a SocketAddress. The final pair of constructors are used for receiving packets. No source or destination addresses are needed in these constructors.

After creating a packet, the process of sending or receiving it involves calling the send or receive method of DatagramSocket. More specifically, you create a packet, then you create a socket. After you create the socket, you call the send method of DatagramSocket to send the datagram packet or use the receive method of DatagramSocket to receive a packet. You can also use the same DatagramSocket to send and receive multiple packets, each going to different destinations and coming from different sources.

Here's an example that sends and receives a datagram packet:


   public class GetTime {
     final private static int DAYTIME_PORT = 13;
     public static void main(String args[]) throws 
             IOException {
       if (args.length == 0) {
             ("Please specify daytime host");
       String host = args[0];
       byte message[] = new byte[256];
       InetAddress address = InetAddress.getByName(host);
       System.out.println("Checking at: " + address);
       DatagramPacket packet = 
           new DatagramPacket(message, message.length, 
                   address, DAYTIME_PORT);
       DatagramSocket socket = new DatagramSocket();
       packet = 
           new DatagramPacket(message, message.length);
       String time = new String(packet.getData());
       System.out.println(The time at " 
               + host + " is: " + time);


By passing the name of a hosting server running the daytime service to the program, you can get the time at the location for that machine. For example:

 java GetTime localhost
   Checking at: localhost/
   The time at localhost is: Fri Apr  2 11:30:46 2004

One potential problem with this example relates to security. For security reasons, most web-accessible machines turn off non-essential services and disable UDP connections through their firewall. As such, you might not find an accessible machine running the daytime service. Linux users can start the service and connect to their own machines. Another option (and for those without a startable service), is to use the TimeServer shown below. TimeServer uses the same DatagramPacket and DatagramSocket classes to create the server side to this program.

The new DatagramSocket(DAYTIME_PORT) line in TimeServer means that you want to listen on whatever port is defined in DAYTIME_PORT. The program doesn't wait until you do the call to the receive method. As is the case when you send the request, you must create a packet for the data. The daytime service ignores the contents of the packet, but you must still create a packet to receive the request. To send back the response in a DatagramPacket, you need to ask the received packet where to send the response.

Here is the TimeServer program:

   import java.util.*;

   public class TimeServer {
     final private static int DAYTIME_PORT = 13;
     public static void main(String args[]) throws 
             IOException {
       DatagramSocket socket = 
             new DatagramSocket(DAYTIME_PORT);
       while (true) {
         byte buffer[] = new byte[256];
         DatagramPacket packet = 
             new DatagramPacket(buffer, buffer.length);
         String date = new Date().toString();
         buffer = date.getBytes();
         // Get response address/port 
         // for client from packet
         InetAddress address = packet.getAddress();
         int port = packet.getPort();
         packet = new DatagramPacket(buffer, buffer.length, 
                 address, port);


If you're on a machine which doesn't allow permission to create a service on a low port, such as 13, change the port in both the client GetTime class and the TimeServer class.

Compile and start the TimeServer class first. This will run forever, simply responding to time requests such as the one sent when you run the GetTime class.

If you aren't familiar with the daytime service, this is defined in RFC 867.

For more information about datagrams, see the networking trail in the Java Tutorial.

Copyright (c) 2004-2005 Sun Microsystems, Inc.
All Rights Reserved.