DatagramSocket and DatagramPacket in Java

Naveen AnamaneniUpdated · 7 min read

UDP (User Datagram Protocol) sends data as separate packets, called datagrams, with no connection between the two sides. Each packet is addressed and sent on its own; it may arrive, arrive twice, arrive out of order, or not arrive at all, and nobody is told. In exchange, UDP is fast and has almost no overhead. Java supports it with two classes: a DatagramPacket is one packet (the bytes plus an address and port), and a DatagramSocket sends and receives packets. In this lesson, you will learn how the two classes work together, write a request-and-reply program, and see UDP's limits in action.

How It Differs from TCP

PointTCP (Socket)UDP (DatagramSocket)
Connectionaccept() and connect firstNone; just send
Server and client classesServerSocket and SocketThe same class, DatagramSocket, on both sides
DataA stream, read with input streamsWhole packets, received one at a time
Message boundariesNone; you define themKept: one send is one receive
Lost dataResent automaticallyLost for good unless your code resends
SizeUnlimited streamOne packet; keep it small (see below)

The Classes

MemberDescription
new DatagramSocket(port)It is used to open a socket on a port, to receive packets there.
new DatagramSocket()It opens a socket on any free port, enough for a client.
socket.send(packet)It sends one packet to the address and port stored in the packet.
socket.receive(packet)It waits for a packet and fills the given packet's buffer.
socket.setSoTimeout(millis)It limits how long receive waits.
new DatagramPacket(bytes, length, address, port)A packet to send.
new DatagramPacket(buffer, length)An empty packet to receive into.
packet.getData(), getLength()The buffer, and how many bytes of it were actually received.
packet.getAddress(), getPort()Who sent the packet, which is where a reply should go.

Example: Request and Reply

Let's see an example in which a client asks for a student's marks and a server replies, followed by the two ways UDP can surprise you:

Udp.java▶ Try it
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
import java.nio.charset.StandardCharsets;
 
public class Udp {
    public static void main(String[] args) throws Exception {
        InetAddress local = InetAddress.getLoopbackAddress();
        try (DatagramSocket server = new DatagramSocket(0, local);
             DatagramSocket client = new DatagramSocket()) {
            int port = server.getLocalPort();
 
            // Server: receive one packet and reply to whoever sent it.
            Thread serverThread = Thread.ofVirtual().start(() -> {
                try {
                    for (int i = 0; i < 2; i++) {
                        byte[] buffer = new byte[1024];
                        DatagramPacket request =
                            new DatagramPacket(buffer, buffer.length);
                        server.receive(request);
                        String text = new String(request.getData(), 0,
                            request.getLength(), StandardCharsets.UTF_8);
                        byte[] reply = ("Marks for " + text + ": 91")
                            .getBytes(StandardCharsets.UTF_8);
                        server.send(new DatagramPacket(reply, reply.length,
                            request.getAddress(), request.getPort()));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
 
            // Client: send a packet, then wait for the reply.
            client.setSoTimeout(2000);
            for (String name : new String[] {"Navika", "Advitha"}) {
                byte[] data = name.getBytes(StandardCharsets.UTF_8);
                client.send(
                    new DatagramPacket(data, data.length, local, port));
                byte[] buffer = new byte[1024];
                DatagramPacket reply =
                    new DatagramPacket(buffer, buffer.length);
                client.receive(reply);
                System.out.println(new String(reply.getData(), 0,
                    reply.getLength(), StandardCharsets.UTF_8)
                    + "  (" + reply.getLength() + " bytes)");
            }
            serverThread.join();
 
            // Nobody answers now: receive() times out instead of failing.
            client.setSoTimeout(300);
            byte[] data = "Srihitha".getBytes(StandardCharsets.UTF_8);
            client.send(new DatagramPacket(data, data.length, local, port));
            try {
                client.receive(new DatagramPacket(new byte[64], 64));
            } catch (SocketTimeoutException e) {
                System.out.println("No reply: " + e.getMessage());
            }
 
            // A buffer that is too small silently cuts the message.
            try (DatagramSocket a = new DatagramSocket(0, local);
                 DatagramSocket b = new DatagramSocket(0, local)) {
                byte[] big = "Hello from PoolString"
                    .getBytes(StandardCharsets.UTF_8);
                a.send(new DatagramPacket(
                    big, big.length, local, b.getLocalPort()));
                DatagramPacket small = new DatagramPacket(new byte[5], 5);
                b.setSoTimeout(2000);
                b.receive(small);
                String got = new String(small.getData(), 0,
                    small.getLength(), StandardCharsets.UTF_8);
                System.out.println("Sent " + big.length
                    + " bytes, received \"" + got + "\"");
            }
        }
    }
}
Output
Marks for Navika: 91  (20 bytes)
Marks for Advitha: 91  (21 bytes)
No reply: Receive timed out
Sent 21 bytes, received "Hello"

Explanation:

  1. Both sides use DatagramSocket. The server's is bound to a known port; the client's gets any free port.
  2. The server calls receive, which waits for a packet. It reads the text from the first getLength() bytes of the buffer, not the whole 1024-byte buffer.
  3. Replying needs no connection: the request packet carries the sender's address and port, so the server addresses its reply there.
  4. The client sends a packet and then waits for one. The timeout matters, because a reply may never come.
  5. "No reply": the server handled two requests and stopped. The third packet was sent successfully, since sending never fails just because nobody is listening, but no answer arrived, and receive gave up with SocketTimeoutException.
  6. The cut-off message: a 21-byte packet was received into a 5-byte buffer. UDP delivered the first 5 bytes and silently threw the rest away. There is no "read the remainder", as there would be with a stream.

How Big Can a Packet Be?

A UDP packet can theoretically carry about 65,507 bytes, but large packets are split into fragments on the way, and losing any fragment loses the whole packet. The safe habit is to keep each packet under about 1,200 bytes, which fits in a single network frame on almost every network. For more data, split it across packets yourself, or use TCP.

When to Choose UDP

Good fitWhy
Voice and video calls, live streamsA late packet is useless; it is better to skip it than to wait
Online gamesThe newest position matters, not a resend of an old one
DNS lookupsOne small question, one small answer; no connection setup
Discovery and broadcast on a local networkOne packet can reach many machines
Metrics and logsLosing an occasional sample is acceptable

When you need every byte, in order, choose TCP. Modern protocols such as QUIC (used by HTTP/3) are built on top of UDP and add their own reliability.

Common Mistakes

Using getData().length instead of getLength(). The buffer is larger than the message; you get the message plus leftover bytes.

A receive buffer that is too small. The extra bytes are dropped without any error.

Expecting an error when nobody is listening. send succeeds anyway; only a missing reply tells you.

Assuming packets arrive in order. If order matters, put a sequence number in each packet.

Interview Corner

What are DatagramSocket and DatagramPacket?

They are Java's UDP classes. A DatagramPacket is one datagram: a byte array with a length, plus the destination (when sending) or source (when received) address and port. A DatagramSocket sends packets with send and waits for them with receive. There is no connection and no separate server class: both sides use DatagramSocket, and the server replies to the address and port found in the packet it received.

When would you use UDP instead of TCP?

When speed and low overhead matter more than guaranteed delivery, and the application can tolerate or handle loss: real-time audio and video, games, DNS queries, service discovery and telemetry. TCP is the choice when all data must arrive complete and in order, as with web pages, file transfer and database connections.

Practice

  1. Easy: Change the server to reply with the name in upper case and the length of the name.
  2. Harder: Make the client resend its request up to three times when receive times out, and report how many attempts it took.

Quick check: UDP

4 questions
1Which class does a UDP server use to receive packets?
2How does a UDP server know where to send a reply?
3A 100-byte packet arrives in a 40-byte buffer. What happens?
4What happens when you send a packet to a port where nothing listens?

Key Takeaways

Was this tutorial helpful?

Lesson 482 of 482