Master the fundamental concepts of tcp/ip from scratch through this focused micro-challenge.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksUDP is connectionless with no handshake or reliability guarantees. For example, a DNS client on port 49152 talks to 8.8.8.8:53 with a single sendto() call. The syscall sequence starts with:
cLoading…
Arguments: AF_INET for IPv4, SOCK_DGRAM for datagrams, IPPROTO_UDP (or 0).
Without getaddrinfo(), you construct the address structure yourself:
cLoading…
Key fields:
sin_family: always AF_INETsin_port: use htons() for network byte ordersin_addr: 32-bit IPv4 addressThen bind() for servers, sendto()/recvfrom() for each datagram. Unlike TCP's connect()/send() pattern, UDP is stateless: every sendto() must carry the destination address, and every recvfrom() tells you who sent the packet. This makes UDP ideal for DNS queries to 8.8.8.8:53 where one request expects one reply.
This task requires you to build a UDP client and server using only raw syscalls. Forgetting htons() on the port field is an extremely common bug on little-endian machines: the value silently becomes garbage instead of erroring. Every DNS resolver and DHCP client on Linux ultimately calls socket(AF_INET, SOCK_DGRAM, 0) and fills sockaddr_in exactly as you do here, since getaddrinfo() is just a convenience wrapper around this sequence.
Given the endpoints and payload of a UDP datagram, compute its on-the-wire framing without touching a real socket - the byte-level work sendto() and the kernel do for you.
Input (stdin): src_ip dst_ip src_port dst_port payload_len, then (only if payload_len > 0) the payload as a hex string. Example: 192.168.1.10 8.8.8.8 49152 53 8 aabbccddeeff0011
Output (stdout):
Every DNS resolver builds exactly this header when it queries a server like 8.8.8.8:53, and htons() is why the ports and lengths live on the wire as big-endian words.