Python · Course navigation

UDP datagrams

Send independent datagrams with no connection and see how UDP differs from TCP.

On this page
Before you start

TCP sockets.

  • Send independent datagrams with no connection and see how UDP differs from TCP.
  • Predict the sample output and explain the state changes.
  • Complete the practice task and check the boundary cases.

The concept

UDP is a connectionless transport protocol. There is no handshake: a sender simply sends a datagram to an address and port. Each datagram is delivered, if it is delivered at all, as one whole unit, so message boundaries are preserved, unlike TCP's byte stream.

UDP itself provides no guarantees beyond an optional checksum. Datagrams can be lost, duplicated, or arrive out of order, and there is no flow or congestion control at the UDP level. That makes it a good fit for DNS lookups, real-time audio and video, and games, where speed matters more than perfect delivery, and for protocols such as QUIC that build their own reliability on top.

The example sends two datagrams over the loopback interface. On loopback they arrive in order and intact, which is why the output is predictable, but that is a property of this local setup. Real networks may reorder or drop packets, and an application using UDP has to handle that itself, for example with sequence numbers, acknowledgements, and timeouts.

Code example

Python
import socket

receiver = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
receiver.bind(("127.0.0.1", 0))
address = receiver.getsockname()

sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sender.sendto(b"one", address)
sender.sendto(b"two", address)

first, _ = receiver.recvfrom(1024)
second, _ = receiver.recvfrom(1024)
sender.close()
receiver.close()
print(first, second)
Output
b'one' b'two'

Follow the code

Open the walkthrough to inspect the example one step at a time.

Show guided walkthrough
Guided walkthroughReady
1import socket
2
3receiver = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
4receiver.bind(("127.0.0.1", 0))
5address = receiver.getsockname()
6
7sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
8sender.sendto(b"one", address)
9sender.sendto(b"two", address)
10
11first, _ = receiver.recvfrom(1024)
12second, _ = receiver.recvfrom(1024)
13sender.close()
14receiver.close()
15print(first, second)

Follow the example

Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.

View the complete dry-run table
Prepared trace of the published program. Some rows group repeated iterations.
Step / lineWhat happensState after stepOutput so far
The receiver binds a UDP socket to a free local port. No listen or accept is needed.—
—
Each sendto is an independent datagram addressed to the receiver. There is no connection.—
—
recvfrom returns exactly one datagram and the sender's address.—
—
Message boundaries are preserved: two sends produce two separate receives.—
b'one' b'two'

Behind the scenes

How Python processes this code

Python runs this source through its interpreter. It creates objects for values and resolves names as each statement runs.

Cost and common mistakes

Each send and receive is O(n) in the datagram size. UDP adds no connection setup.

  • UDP does not guarantee delivery or order. Do not assume that a datagram you sent will arrive.
  • A recvfrom buffer smaller than the datagram silently truncates it. Size the buffer for the largest message you expect.
  • Large datagrams can be fragmented or dropped by the path. Keep payloads small, commonly under roughly 1200 bytes for the Internet.

Try it yourself

Which protocol would you choose for a live video call, and why?

Reveal answer and reasoning

Typically UDP-based transport. A late frame is worthless, so retransmitting old data (as TCP would, with head-of-line blocking) hurts more than skipping it.

Further reading