Network programming in C
You write TCP and UDP clients and servers with sockets, handle many connections with select, poll and epoll, and build robust code that never trusts network data.
Level 301 · 22 lessons · 21 practice labs
Lessons
Socket basics
- Network byte order and address structures
- Name resolution: getaddrinfo for IPv4 and IPv6
- A TCP client: connect, send, recv
- A TCP server: bind, listen, accept
- Partial reads and writes: receiving whole messages
- Short task: an echo server
Many connections
- One process per client
- Many connections with select and poll
- A scalable server with epoll
- Non-blocking sockets and timeouts
- Short task: a multi-user chat server
Protocols
- UDP: sendto, recvfrom and lost packets
- Message framing: a length-prefixed protocol
- An HTTP request over a raw socket
- A tiny HTTP server: request line and headers
- A TLS client with OpenSSL and certificate verification
- Short task: collect service banners from the lab targets
Robust network code
- Never trusting network data: length and bounds checks
- Resource limits: connections, time and memory
- Fuzzing your own protocol parser
- Short task: harden your server against malformed requests
Capstone
- Capstone: a parallel service checker with timeouts
Practice labs
- Printing an address structure readably: Write a helper that prints sockaddr_in and sockaddr_in6 structures as address and port with inet_ntop.
- A client for the lab time service: Write a client that connects to the time service on the lab target over TCP, reads the reply and explains connection errors.
- Reading until exactly N bytes arrive: Write a recv_exact function that joins partial recv returns and errors if the connection closes early.
- A TCP server that can be restarted: Fix a server that fails with 'Address already in use' after a quick restart and stop it leaking resources when clients close.
- Listing all addresses of a name: Write a small tool that lists the IPv4 and IPv6 addresses of a lab host name with getaddrinfo.
- A connection that tries addresses in turn: Write a function that tries getaddrinfo results in turn, returns the first successful connection and frees the addrinfo.
- Telling resolution errors apart: Write code that separates not-found, temporary failure and timeout with gai_strerror and retries only temporary failures.
- A multi-client counter server with poll: Write a single-process server with poll that tells each client how many people are connected.
- Getting past select's descriptor limit: Move a select-based server that corrupts memory above FD_SETSIZE to poll and test it with a thousand connections.
- An edge-triggered epoll loop: Fix connections that stall in an EPOLLET server because data is not read until EAGAIN.
- Putting a timeout on connect: Write a connect function with non-blocking connect and poll that waits at most two seconds for the lab targets.
- Measuring packet loss over UDP: Write a client that sends numbered UDP packets to the lab echo service and computes the share that never return.
- A length-prefixed message codec: Write send and receive functions for messages with a 4-byte length prefix, rejecting lengths above a limit.
- Getting an HTTP status over a raw socket: Write a tool that sends a HEAD request to the lab web target over a raw socket and parses the status code and Server header.
- Verifying the host name in a TLS client: Add chain and host-name verification to an OpenSSL client that skips it so the wrongly named target is refused.
- Limiting header line length: Add a length limit to a server that reads the request line into a fixed buffer and answer long lines with 431.
- Dropping slow clients with a timeout: Stop clients that send data very slowly from holding connections by adding a per-client time limit.
- Concurrent connection and memory caps: Add a per-IP connection limit and a total buffer memory cap to a server so it politely refuses beyond them.
- Testing a frame parser with fuzzing: Run the message frame parser under a libFuzzer target, fix the crash it finds and add the input as a test.
- Reconnecting with growing back-off: Turn a client that dies when the server restarts into one that reconnects with capped growing back-off and resumes from the line it reached.
- Decoding a four-byte frame header: Write a function that turns a four-byte header of type and length fields in network byte order into a struct and rejects short input.
About this course
You write TCP and UDP clients and servers with sockets, handle many connections with select, poll and epoll, and build robust code that never trusts network data.
What you will learn
- Socket basics
- Many connections
- Protocols
- Robust network code
- Capstone
Prerequisites
You should be comfortable with the level 101 and 201 topics of the same path.
Lab environment
Lessons run in your own Kali Linux terminal in the browser, connected to a private lab network. Nothing to install.
Frequently asked questions
- Is this course right for my level?
- The course is at level 301; it assumes you know the topics of the lower-level courses.
- Is there anything to install?
- No. Every lesson runs in your own lab environment that opens in the browser.
- How do lessons work?
- Each lesson has 8 to 10 steps and a short quiz. Early steps show the command to type, later steps give less help; if two attempts fail, the solution opens.
- Can I try it for free?
- Yes. The first three lessons of every course are free.