Networking in C · beginner · ~8 min

TCP vs UDP — when to pick which

Pick the right transport protocol for the job.

Lesson

Two transport protocols

When you write networked C, you choose one of two transport protocols. Each handles delivery very differently.

TCP (Transmission Control Protocol)

TCP gives you a reliable, ordered stream of bytes:

  • Bytes arrive in order.
  • There are no duplicates and no loss.
  • Delivery may be delayed if a lost packet had to be resent.

The kernel does the hard work for you. It handles retransmits (resending lost data), ordering, and flow control (matching the sender's speed to what the receiver can handle).

TCP powers almost everything you use directly: HTTP, SSH, SMTP, and Git.

UDP (User Datagram Protocol)

UDP is simpler and does far less for you. Each sendto() call becomes exactly one packet on the wire. That packet:

  • may arrive,
  • may never arrive, or
  • may arrive out of order.

If you need reliability, you must build it yourself on top of UDP.

UDP is used by DNS, video conferencing, online gaming, and QUIC.

Message boundaries: the key difference

A message boundary marks where one message ends and the next begins. TCP and UDP treat these very differently.

  • TCP is a byte stream. It does not preserve boundaries. Two send() calls of 4 bytes each might arrive as a single recv() of 8 bytes.
  • UDP is datagram-based. It preserves boundaries: one sendto() arrives as one packet at the receiver. But delivery is not guaranteed.

Which to use here

For everything in this course, use TCP unless an exercise specifically calls for UDP.

Code examples

int tcp = socket(AF_INET, SOCK_STREAM, 0);  /* TCP */
int udp = socket(AF_INET, SOCK_DGRAM,  0);  /* UDP */

Common mistakes

  • Expecting message boundaries from TCP. They do not exist. TCP is a byte stream, so a single recv() may return part of a message, a whole message, or several messages joined together. Frame your messages yourself, using a length prefix or a delimiter.

Summary

  • TCP = reliable, ordered byte stream. No message boundaries.
  • UDP = best-effort datagrams. Boundaries preserved, delivery not guaranteed.
  • TCP retransmits, orders, and flow-controls for you; with UDP you build reliability yourself.
  • Default to TCP unless an exercise says otherwise.

Practice with these exercises