Poplar ProductivityWare Articles:
UDP, TFTP, and IP Multicast in Java,
by Jennifer Hodgdon

I was recently working on a Java-programming project that involved some inter-process and inter-hardware communication. Unfortunately, since the client wanted to replicate the exact behavior of an older system with the software I was writing, we were not able to use the current industry standard TCP/IP sockets for communication. Instead, the specs called for a more complex communications protocol using UDP networking, TFTP, and IP Multicast. Getting the software working in Java involved some research, as well as some trial and error, so I thought I would write an article to give anyone else in the same situation the chance to avoid some of the work I did.

So, this article is a basic outline of how to get UDP, TFTP, and IP Multicast working in Java, along with some basic information about the three protocols and suggestions for further reading. It is intended for software developers who have at least intermediate knowledge of the Java language and Java development; background-level knowledge of TCP/IP will also be helpful for understanding some concepts. Since both TFTP and IP Multicast are based on UDP, I suggest that all readers start with the introduction and UDP sections; however, the TFTP and IP Multicast sections do not depend on each other, and either or both can be skipped if desired. I have also provided some fairly basic (but working) sample Java classes for free download.

Comments on this article are always welcome! If you have suggestions, questions, or any other comments, please contact Poplar ProductivityWare.

Contents of this article:


Introduction to UDP, TFTP, and IP Multicast

UDP (User Datagram Protocol), like TCP, is a general-purpose communications protocol for inter-process and inter-computer communications that runs on top of IP (Internet Protocol). The details of TCP and UDP are quite different, however. One difference between TCP and UDP is that TCP has more hand-shaking and error checking built into the protocol, and a guarantee that data packets arrive in the correct order. Another difference is that instead of starting the communications process by negotiating to open a socket directly between two processes as in TCP, in UDP one process simply starts sending to a particular port at a particular IP address, while another one begins receiving, and thus communication is established. There is also some terminology that is different between the two protocols: TCP sends "packets" through its sockets, and UDP sends "datagrams" or "datagram packets". The Wikipedia entry on UDP is a good starting point for further reading on UDP.

TFTP (Trivial File Transfer Protocol) is a protocol that uses UDP to transfer files from one computer to another (much as the more familiar FTP uses TCP to transfer files). Like FTP, TFTP consists of a server-side application and a client-side application, but TFTP is a much simpler protocol with only minimal error checking built in. The server basically waits for a client to contact it on a specified port with a particular UDP datagram containing information about the file transfer request, and then the server sends (or receives) the datagrams containing chunks of the file, with an acknowledgement exchange after each packet. Technical details of the TFTP protocol specification can be found in RFC 1350 (1992), and the Wikipedia article on TFTP has more general background information.

IP Multicast is a protocol that uses UDP for efficient broadcast of messages to multiple receiving applications on multiple hosts. The broadcasting application sends its messages to an IP address in a particular reserved range, and applications on other computers on the same network listen to the same port on the same address to receive the message. In between, assuming that both the sending and receiving computers, as well as the network, have IP Multicasting installed, an efficient mechanism is used to send minimal copies of the message through the network. Note that the "message" sent can be any type of data -- it doesn't have to be text. The Wikipedia article on IP Multicast is a good starting point for further reading.

Adding UDP to a Java Application

In Java, the basic classes for UDP networking are java.net.DatagramSocket and java.net.DatagramPacket; you will probably also need other classes in the java.net package, such as java.net.InetAddress. These classes are provided by Sun as part of the standard J2SE distribution, and their full documentation can be found in the standard Sun Javadoc API documentation Use of these classes to do communications by UDP between two processes (a "sender" and a "receiver") is fairly straightforward. Here are the steps:

  1. Decide on a port for communication, and figure out the IP address of the receiving computer (which can be "localhost" if the two communicating processes are on the same computer). For this illustration, assume that we want to communicate on port 7777, and the receiving computer is at IP address 12.34.56.78.
  2. Create new instances of java.net.DatagramSocket in both the sender and receiver process. Important note: It might seem like you should try to create a socket with a port and address on it, but I have never gotten this to work without an exception being thrown. So my advice is to use the no-argument default constructor on the sending side, and put the port and address on the packet (see below). On the receiving side, you'll need to construct a socket with the desired port. Code for this:
    // Sending
    DatagramSocket sock = new DatagramSocket();
    // Receiving
    DatagramSocket sock = new DatagramSocket(7777);
  3. Create a new instance of java.net.DatagramPacket in the sending process, containing the information you want to send, and using a constructor that contains the IP address and the port. For instance, if you want to send a message contained in a byte array called "buf", here is the code to create the packet:
    DatagramPacket pack = new DatagramPacket(buf, buf.length, InetAddress.getByName("12.34.56.78"), 7777);
  4. Create a new instance of java.net.DatagramPacket in the receiving process, to receive the data; note that if the sent information exceeds the size of the receiving buffer, the incoming data will be truncated:
    byte[] buf = new byte[LARGE_SIZE];
    DatagramPacket pack = new DatagramPacket(buf, buf.length);
  5. Set up the receiving side to receive on the socket -- it will wait until information comes in (or forever if no information arrives):
    sock.receive(pack);
    Note that only one process can be receiving/listening on a given port at the same time, on the same computer.
  6. Send the datagram through the socket from the sender side:
    sock.send(pack);
  7. Once the receive completes, you can do something with the information on the receiving side. Then, if you have more information to receive, reset the length on the receiving datagram packet, so that it is ready to receive a full-length message the next time:
    pack.setLength(buf.length);
    sock.receive(pack);

The UDPSender and UDPReceiver classes in the download file (below) are implementations of the above steps.

Adding IP Multicast to a Java Application

IP Multicast in Java requires only a small amount of coding beyond the basic UDP coding described above. In fact, there are really only a couple of extra steps:

The IPMulticastSender and IPMulticastReceiver classes in the download file (below) are implementations of the above steps.

For further reading, I recommend these two articles on IP Multicast programming:

Adding TFTP to a Java Application

In principle, you could get TFTP working in Java via the exact same mechanisms used above. However, TFTP requires very specific packets to be sent back and forth, with various pieces of header information, so it is easier to create TFTP applications in Java by using the Apache Jakarta Commons Net classes.

Note: When downloading the Commons Net classes for use in TFTP, please be aware that there is a serious bug in the TFTPClient class in the 1.41 release (the current release as of September 2006, when this article was written). Check the JIRA bug database for the Apache project (which you can find from the Apache Jakarta Bugs Page) and search for TFTPClient for more information; the bug caused the last packet of a sent file to be dropped. Also, although the JIRA bug database (more up-to-date than Bugzilla) states the bug has been fixed in the overnight build source code, I do not think that is the case. So, in order to get TFTP working, until they get it fixed on their end, my suggestion is: (a) download the source code for the stable release, (b) pick up my download file (below) and substitute the TFTPClient.java file from it into the source code, and (c) build the JAR file for the package and use it instead of the released JAR file (you will probably see some build errors and warnings, but none of them seem to apply to TFTP).

Anyway, assuming that you have a working version of the Apache Jakarta Commons Net package, here are the steps needed to add a TFTP client to your application:

  1. Create a new instance of org.apache.commons.net.tftp.TFTPClient using the default constructor, and open a connection to the designated TFTP port (normally, TFTP uses port 69, but as long as your client and server agree, you can use a different port):
    TFTPClient client = new TFTPClient();
    client.open(69);
  2. Use the TFTPClient.sendFile and TFTPClient.receiveFile methods to send files to and receive files from your TFTP server. See the Javadoc API documentation for the Commons Net package for more information on these methods.

If you need to add a TFTP server to your application, it is more complex, since the Commons Net package does not contain a class that acts as a TFTP server. So, you will have to duplicate the proper TFTP protocol behavior yourself, using some of the Commons Net classes. Here are the steps:

  1. Choose a port for your TFTP server. The default port is 69, but you may not have permission to use low-numbered ports for custom applications on your server, so you might have to choose a higher port number (2269, for instance).
  2. Create a new instance of org.apache.commons.net.tftp.TFTP using the default constructor, and open a connection to the chosen TFTP port:
    TFTP server = new TFTP();
    server.open(69);
  3. Check for incoming TFTP client connections using TFTP.receive(). If an incoming connection occurs, the method will return an org.apache.commons.net.tftp.TFTPPacket object. If timeout occurs before an incoming connection happens, the method will throw either a java.net.SocketException or a java.io.InterruptedIOException, and you can check again (looping until a packet is received).
  4. Check to see what type of packet was received -- it should be either a "read request" or "write request" packet, if the client is obeying the TFTP protocol.
  5. A "read request" packet means that the client wants you to send a file. To do that, you'll need to:
    1. Break the file up into chunks of 512 bytes.
    2. Put each chunk into an org.apache.commons.net.tftp.TFTPDataPacket object; note that each packet must be sequentially numbered and contain the full number of bytes. The last packet has a smaller number of bytes (or zero if the file had exactly an even multiple of bytes), and signals the client that file transmission is complete.
    3. Send the packet using the TFTP.send() method
    4. Use TFTP.receive to wait for an acknowledgement packet from the client.
    5. After acknowledgement is received with the correct packet number, send the next packet.
  6. A "write request" packet means that the client wants to send you a file. To do that:
    1. Start by sending an acknowledgement packet to the client (using org.apache.commons.net.tftp.TFTPAckPacket), with block number 0. This will signal the client that you are ready to receive the file.
    2. Wait for data packets to come in, by using TFTP.receive, sending an acknowledgement after each one, and saving the data from each. A packet with less than the maximum number of bytes signals the end of the file.
  7. There are some other details of the protocol that you might also want to implement. For instance, if you get something unexpected from the client, you can send them an error packet describing what happened, and if an expected packet (acknowledgement or data) in the sequence is missed, you can signal the client by re-sending the previous packet from your end. Read the RFC containing the TFTP specifications for more information. You may also find it instructive to read the source code for the TFTPClient class (which you can download from Apache -- see above), since a TFTP client goes through a similar sequence of data sending and receiving.

The TFTPServerApp and TFTPClientApp classes in the download file (below) are implementations of the above steps.

Download Sample Java Classes

To illustrate all of the networking examples above, I have created sample Java classes, which you can download here in a zip file. The file size is 90.7 KB (92,973 bytes), and it includes public domain Java J2SE 5.0 source code, Javadoc, jar file, a fix for the Apache TFTP bug described above, and a "Readme" file.


Poplar ProductivityWare: your Seattle-area source for web databases, web programming, Palm OS applications, and analytical/modeling software

Home | Web Programming | Custom Software | Articles | Downloads | Testimonials | Values | Contact Us

Poplar ProductivityWare® is a trademark registered in the U.S. Patent and Trademark Office

Copyright (C) 2003-2008 Poplar ProductivityWare LLC

On This Site:

Home: See an overview of the company

Web Programming: Find out how we can improve your web site

Custom Software: Learn about our custom Palm OS and analytical software services

Articles: Get free information on a variety of topics

Downloads: Download free software

Testimonials: See what other clients have said

Values: Learn about the values that govern our business, and read our privacy policy

Contact Us: Locate our phone, email, and mailing addresses


RSSRSS Feed: Keep track of our new articles and downloads by subscribing (learn about RSS here)


Search the Poplar ProductivityWare site using Google: