DatagramSocket and DatagramPacket in Java
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
| Point | TCP (Socket) | UDP (DatagramSocket) |
|---|---|---|
| Connection | accept() and connect first | None; just send |
| Server and client classes | ServerSocket and Socket | The same class, DatagramSocket, on both sides |
| Data | A stream, read with input streams | Whole packets, received one at a time |
| Message boundaries | None; you define them | Kept: one send is one receive |
| Lost data | Resent automatically | Lost for good unless your code resends |
| Size | Unlimited stream | One packet; keep it small (see below) |
The Classes
| Member | Description |
|---|---|
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:
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 + "\"");
}
}
}
}Marks for Navika: 91 (20 bytes)
Marks for Advitha: 91 (21 bytes)
No reply: Receive timed out
Sent 21 bytes, received "Hello"Explanation:
- Both sides use
DatagramSocket. The server's is bound to a known port; the client's gets any free port. - The server calls
receive, which waits for a packet. It reads the text from the firstgetLength()bytes of the buffer, not the whole 1024-byte buffer. - Replying needs no connection: the request packet carries the sender's address and port, so the server addresses its reply there.
- The client sends a packet and then waits for one. The timeout matters, because a reply may never come.
- "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
receivegave up withSocketTimeoutException. - 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 fit | Why |
|---|---|
| Voice and video calls, live streams | A late packet is useless; it is better to skip it than to wait |
| Online games | The newest position matters, not a resend of an old one |
| DNS lookups | One small question, one small answer; no connection setup |
| Discovery and broadcast on a local network | One packet can reach many machines |
| Metrics and logs | Losing 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
- Easy: Change the server to reply with the name in upper case and the length of the name.
- Harder: Make the client resend its request up to three times when
receivetimes out, and report how many attempts it took.
Key Takeaways
Was this tutorial helpful?