152 / 163 · C11 · 8 min
Distributed Systems
Distributed systems assemble many machines over a network into one service. Individual hosts, disks and links fail, yet redundancy can make the whole appear almost never to fail. Communication is inherently lossy, so checksums, acknowledgements and retransmissions are required to build usable protocols.
In this lesson
Failure as Challenge and Opportunity
A single machine can crash, a disk can fail, a cable can be cut. The real skill is combining many imperfect parts so the service as a whole looks continuously available to clients. That idea underpins every large modern web site.
The Unreliable Nature of Communication
Packets vanish on the wide-area Internet and on local high-speed fabrics alike, because of electrical noise, broken hardware or exhausted switch memory. Even when every component is healthy, a traffic burst can overflow buffers and force drops. Every send must therefore be treated as possibly unsuccessful.
Detecting Corruption with Checksums
Before transmission a sum (or a stronger CRC) is computed over the bytes and sent with the packet. The receiver recomputes and compares; a mismatch means the packet is discarded. A simple additive checksum is cheap yet misses some errors, so designers trade speed against detection power.
Building Reliable Transport on an Unreliable Layer
A connectionless best-effort service only promises to try. Reliable byte streams add timeouts, acknowledgements and retransmissions. Loss, duplication and reordering are absorbed at this layer so applications can assume data eventually arrives intact.
Pitfalls
- Treating the network as a perfectly reliable pipe
- Forgetting to handle duplicate packets
- Choosing a checksum too weak to catch corruption
Run an example
Minimum C11 · complete program · Download .c
#include <stdio.h>
#include <string.h>
#define BUF 64
typedef struct {
char data[BUF];
unsigned checksum;
} Packet;
unsigned compute_cs(const char *d) {
unsigned s = 0;
for (int i = 0; d[i]; i++) s += (unsigned char)d[i];
return s;
}
int main(void) {
Packet p;
strcpy(p.data, "hello");
p.checksum = compute_cs(p.data);
printf("Client: sending '%s' cs=%u\n", p.data, p.checksum);
for (int try = 1; try <= 2; try++) {
printf("Try %d: ", try);
if (try == 1) {
printf("lost\n");
continue;
}
printf("ok\n");
unsigned rcs = compute_cs(p.data);
if (rcs == p.checksum) {
printf("Server: got '%s' ok, reply 'ack'\n", p.data);
}
}
return 0;
}
Compile locally
gcc -std=c11 -Wall -Wextra -Wpedantic -Werror ostep-48-distributed-systems.c -o example && ./exampleExpected result
Client: sending 'hello' cs=532
Try 1: lost
Try 2: ok
Server: got 'hello' ok, reply 'ack'
CHECK YOUR UNDERSTANDING
Close the answer. Explain it.
Why can packets still be lost even when every link and host is working correctly?
Show a reference answer
Buffers inside routers or end hosts overflow during traffic bursts and must drop the extra packets.
Check the sources
Drafts and official chapters change. The version mark is only the example’s minimum.