Datagram network traffic is a kindred spirit to the underlying packet-based Ethernet and IP (Internet protocol) layers. Unlike a stream-based connection such as TCP, datagram transports such as UDP transmit each “packet” or chunk of data as a single entity with no necessary relation to any other. A common analogy is that TCP is like talking on the telephone, while UDP is like sending postcards, or maybe FAX messages.
The differences show up most in error handling. Packets can, like postcards, go astray. When was the last time the postman rang your bell to tell you that the post office had lost one of several postcards it was supposed to deliver to you? It doesn’t happen, right? Because they don’t keep track of them. On the other hand, when you’re talking on the phone and there’s a noise burst -- like somebody yelling in the room, or even a bad connection -- you can ask the person at the other end to repeat what they just said.
With a stream-based connection like a TCP socket, the network transport layer handles errors for you: it asks the other end to retransmit. With a datagram transport such as UDP, you have to handle retransmission yourself. Kind of like numbering the postcards you send, so that you can go back and resend any that don’t arrive -- a good excuse to return to your vacation spot, perhaps.
Another difference is that datagram transmission preserves message
boundaries. That is, if you write 20 bytes and then write 10 bytes
when using TCP, the program reading from the other end will not know
if you wrote one chunk of 30 bytes, two chunks of 15, or even 30
individual characters.
With a
DatagramSocket
, you construct a
DatagramPacket
object for each buffer, and its
contents are sent as a single entity over the
network; its contents will not be mixed together with the contents of
any other buffer. The DatagramPacket
object has
methods like getLength( )
, setPort( )
, and so on.
Example 15-8 is a short program that connects via UDP
to the Daytime
date and time server used in Section 15.5. Since there is no real notion of
“connection” with UDP, even
services that only send you data must
be contacted by sending an empty packet, which the UDP server uses to
return its response.
Example 15-8. DaytimeUDP.java
public class DaytimeUDP { /** The UDP port number */ public final static int DAYTIME_PORT = 13; /** A buffer plenty big enough for the date string */ protected final static int PACKET_SIZE = 100; // main program public static void main(String[] argv) throws IOException { if (argv.length < 1) { System.err.println("usage: java DayTime host"); System.exit(1); } String host = argv[0]; InetAddress servAddr = InetAddress.getByName(host); DatagramSocket sock = new DatagramSocket( ); // Allocate the data buffer byte[] buffer = new byte[PACKET_SIZE]; // The udp packet we will send and receive DatagramPacket packet = new DatagramPacket( buffer, PACKET_SIZE, servAddr, DAYTIME_PORT); /* Send empty max-length (-1 for null byte) packet to server */ packet.setLength(PACKET_SIZE-1); sock.send(packet); Debug.println("net", "Sent request"); // Receive a packet and print it. sock.receive(packet); Debug.println("net", "Got packet of size " + packet.getLength( )); System.out.print("Date on " + host + " is " + new String(buffer, 0, packet.getLength( ))); } }
I’ll run it to my server just to be sure that it works:
$ jikes +E -d . DaytimeUDP.java $ java DaytimeUDP darian Date on darian is Sat Jan 27 12:42:41 2001 $
3.144.123.155