When you open a web page, your request does not travel as one stream. It is cut into packets: small pieces, each carrying the address it is going to. Routers pass each packet along on its own, and links are shared by everyone's packets at once. This is packet switching, and it is why one busy line does not block the whole internet. (The old telephone network instead reserved a whole circuit for each call: circuit switching.)
Five layers
Networking is split into layers. Each layer solves one problem and uses the layer below it, so a web browser never needs to know whether the bits travel over Wi-Fi or fibre.
| Layer | Job | Examples | Its unit of data |
|---|---|---|---|
| 5. Application | what the programs say to each other | HTTP, DNS, email | message |
| 4. Transport | from one program to another; reliability | TCP, UDP | segment |
| 3. Network | from one computer to another, across many networks | IP | packet |
| 2. Link | across one link, to the next device | Ethernet, Wi-Fi | frame |
| 1. Physical | bits as signals: light, radio, voltage | fibre, copper | bit |
The OSI model used in many textbooks has seven layers: it adds Presentation and Session between Transport and Application. The internet itself follows the five above (often drawn as four, with Link and Physical together).
Encapsulation
On the way down, each layer wraps the data from the layer above with its own header: who it is from, who it is for, and what it needs to do its job. On the way up, the receiver removes the headers in the opposite order.
message = "GET /index.html"
segment = {"src_port": 51000, "dst_port": 80, "data": message}
packet = {"src_ip": "192.168.1.10", "dst_ip": "93.184.216.34", "data": segment}
frame = {"src_mac": "aa:bb:cc:00:00:01", "dst_mac": "aa:bb:cc:00:00:fe", "data": packet}
# The receiver removes the layers in the opposite order.
inside = frame
for layer in ["frame", "packet", "segment"]:
header = [key for key in inside if key != "data"]
print(layer, "header:", header)
inside = inside["data"]
print("message:", inside)Headers cost space. A full Ethernet frame carries 1460 bytes of data under 58 bytes of headers, but a tiny message is mostly headers:
headers = {"TCP": 20, "IP": 20, "Ethernet": 18}
total_headers = sum(headers.values())
for data in [1460, 10]:
frame = data + total_headers
useful = round(100 * data / frame, 1)
print(data, "bytes of data in a", frame, "byte frame:", useful, "% useful")Common mistakes
- Thinking a router reads the web page: a router looks at the IP header and passes the packet on. Only the two end computers read the application data.
- Mixing up the units: TCP sends segments, IP sends packets, Ethernet sends frames.
- Thinking the layers are separate programs that run one after the other. They are code in your computer's operating system and network card, working on every packet together.
Quick check
My notes
Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.