SubnetLayerProtocols

Requests, Responses, and Why They Are Not Packets

A message is a run of bytes in a stream

Step 1 of 2 — understand the idea. Read this first and the packet trace will confirm what you already expect, instead of teaching you two things at once.

What you'll be able to do

Before this lesson — it builds directly on:
TCP gives HTTP a reliable, ordered stream of bytes. That sounds like everything you could want — but it leaves one problem completely unsolved. TCP does not preserve boundaries. If the server writes a whole response in one go, TCP may deliver it in four pieces. If it writes three responses, TCP may deliver them glued together as one lump of bytes. So HTTP cannot rely on 'a message arrived'. It has to be able to look at a stream of bytes and say: this message ends here, and the next one starts there. That is what the blank line and Content-Length are for.

✗ Common misunderstanding: One packet carries one HTTP request or response.

Why that's wrong: TCP is a byte stream with no message boundaries. It splits by size and coalesces by buffer state, neither of which knows anything about HTTP.

Correct model: A message is a RANGE in a byte stream. Reassemble the stream first, then find messages in it by their framing.

The packets prove it: The persistent-connection trace carries three complete requests in one packet; the large-response trace splits one response across several.

✗ Common misunderstanding: A 404 or a 500 means something is wrong with the network.

Why that's wrong: Both are complete HTTP transactions: the connection worked, the request arrived, and the server answered. The answer was just unwelcome.

Correct model: Any HTTP status at all proves the whole stack beneath it worked. 4xx points at the request, 5xx at the server.

The packets prove it: The server-error trace shows a full handshake, a delivered request, and a 500 — every layer below HTTP demonstrably fine.

Watch these fields in the lab: tcp.payload

Everything in this module is HTTP/1.1. That matters, because HTTP/1.1 is the version you can read straight out of a packet: the request line, the headers and the blank line are ordinary text, which is why it is the right version to learn on. The newer versions carry the same ideas — a method, a path, headers, a status — but they no longer look like text on the wire. HTTP/2 takes those same headers and compresses them into a binary format, and lets many requests share one TCP connection at once instead of queueing. HTTP/3 goes further: it does not use TCP at all. It runs over QUIC, which runs over UDP. So an HTTP/3 capture has no TCP handshake and no TLS records — QUIC does both jobs itself.
HTTP/1.1
Text-framed, one request at a time per connection (with pipelining rarely used). What this module teaches, and what you can read in a hex dump.
HTTP/2
Same semantics, binary framing, compressed headers, many concurrent streams over one TCP connection. Still TCP, still TLS.
HTTP/3
Same semantics over QUIC over UDP. A different stack — no TCP handshake and no separate TLS record layer in the capture.

✗ Common misunderstanding: HTTP is a text protocol.

Why that's wrong: That is true of HTTP/1.1 only. HTTP/2 has been binary-framed since 2015 and HTTP/3 is binary over QUIC, and between them they carry most web traffic.

Correct model: HTTP's *semantics* — methods, status codes, header fields — are shared across versions and defined separately. Only HTTP/1.1's *syntax* is text.

The packets prove it: Every HTTP capture in this module is HTTP/1.1, which is why the request line is legible in the byte view. An HTTP/2 capture of the same request would show HPACK-compressed binary frames.

Watch these fields in the lab: tcp.payload

✓ Concept check — before you open the packets

These test the idea, not the trace. You should be able to answer them from the explanation above.

Why does HTTP need Content-Length when TCP already delivers everything reliably?

A monitoring tool counts HTTP requests by counting packets to port 80. What will it get wrong?

Now that you understand the concept, observe how it appears in the packet exchange.

The lab runs a real simulated capture — pause, step, click any packet, and inspect every byte.