Ran Wei/CS Series/11
中文
Computer Science Fundamentals — Ran Wei

Module 11: Networks and the web

Follow data from an application to a network and back. Frame a TCP stream and build a finite local HTTP client/server experiment.

≈ 5 hours4 sessions2 labs8 exercises6 quiz questions

By the end you can

  • Describe network layers and addressing.
  • Explain DNS resolution.
  • Distinguish TCP streams and UDP datagrams.
  • Implement bounded message framing.
  • Interpret HTTP methods and statuses.

Before you start

Recommended modules: 02, 10.

Know bytes, processes and threads. Labs use loopback 127.0.0.1 and an automatically assigned port; no external services are contacted.

Contents

Study plan

5 hours

Four 75-minute sessions including practice. Allow longer for extensions or unfamiliar prerequisites. Progress is saved locally and shared between language editions.

Session 175 min
Concepts and worked examples
Session 375 min
Apply and extend
1

Layers and packet delivery

Applications define messages; transport protocols connect endpoints; IP routes packets between networks; link technologies move frames across a local hop. Each layer adds information needed for its responsibility. A socket endpoint includes an address and port: the address identifies a network destination, while the port selects a service context. A packet can cross several routers; its route is not the same as an application-level conversation. Loss, delay and reordering are normal conditions a protocol must account for.

Check your understanding

Why does a host need ports in addition to an IP address?

Worked solution

To distinguish service endpoints on that host.

2

Names and DNS

DNS maps domain names to records, including addresses. A resolver can consult caches and query the distributed hierarchy. Cached records have lifetimes; changing a record does not instantly update every client. A hostname is not inherently one permanent IP address. The URL also includes a scheme, path and possibly a port or query. Our lab uses numeric loopback to isolate protocol behaviour from external DNS and routing; it does not demonstrate a full public DNS lookup.

Check your understanding

Does changing a DNS record immediately invalidate all caches?

Worked solution

No; cached records can remain until their allowed lifetime expires.

3

TCP and UDP

TCP provides an ordered byte stream with transport-level reliability and flow control. It does not preserve application message boundaries: one send may require several reads, or several sends may arrive in one read. A zero-length recv result signals the peer has closed its sending side. UDP sends datagrams, retaining boundaries but not guaranteeing delivery or ordering. Choose around application requirements. A timeout indicates the caller did not complete in time, not that the peer definitely did no work.

Check your understanding

Can recv(100) return fewer than 100 bytes?

Worked solution

Yes; loop until the frame's required bytes arrive or the connection ends.

4

Framing and defensive parsing

A protocol can use delimiters, fixed widths or length prefixes. Our frame contains a four-byte unsigned big-endian length followed by that many UTF-8 bytes. Read the header exactly, validate the length against a maximum, then read the body exactly and decode it. Length counts bytes, not characters. The helper deliberately limits each recv to two bytes so partial reads are exercised. Reject truncated frames rather than silently treating partial content as a valid message.

Check your understanding

Why validate length before allocating or reading the body?

Worked solution

To bound resource use from untrusted input.

5

HTTP, HTTPS and request semantics

HTTP expresses requests with methods, targets and headers, and responses with status codes, headers and optional bodies. GET retrieves a representation; POST requests resource-specific processing. 200 indicates success; 404 indicates no matching resource. JSON is one body format, independent of HTTP itself. HTTPS uses TLS to authenticate the server and protect traffic under its trust assumptions. Encryption does not validate application input or authorise a user. Retrying a timed-out mutation needs an idempotency design to avoid duplicates.

Check your understanding

Does HTTPS alone prevent SQL injection?

Worked solution

No; secure transport and safe database queries solve different problems.

6

Common misconceptions

  • recv size is a maximum, not an exact-message promise.
  • Local success does not test internet routing, DNS or TLS.
7

Lab setup

Download each script and run it in a terminal with Python 3.11 or later: python m11_stream.py. On Windows, py -3 is an alternative; on some systems use python3. The labs use only the standard library. Predict the result before running, then complete the variations. Run without -O so assertions remain enabled. Outputs below were captured by the builder. Code and output are identical in both language editions.

8

Lab 1 — Frame a stream

One finite server sends a frame and closes. The client assembles partial reads and checks a 1024-byte limit.

Download m11_stream.py

"""Receive a length-prefixed message even when reads return partial chunks."""
import socket
from threading import Thread
def read_exact(stream, count):
    result = bytearray()
    while len(result) < count:
        chunk = stream.recv(min(2, count - len(result)))
        if not chunk:
            raise EOFError("connection closed before complete frame")
        result.extend(chunk)
    return bytes(result)

with socket.socket() as listener:
    listener.bind(("127.0.0.1", 0)); listener.listen(1); listener.settimeout(5)
    payload = b"Dune,Foundation"
    errors = []
    def serve():
        try:
            connection, _ = listener.accept()
            with connection:
                connection.sendall(len(payload).to_bytes(4, "big") + payload)
        except Exception as error:
            errors.append(error)
    worker = Thread(target=serve); worker.start()
    with socket.create_connection(listener.getsockname(), timeout=5) as client:
        length = int.from_bytes(read_exact(client, 4), "big")
        if length > 1024: raise ValueError("frame too large")
        result = read_exact(client, length)
    worker.join(timeout=5)
    assert not worker.is_alive() and not errors and result == payload
    print("frame bytes:", length, "decoded:", result.decode("utf-8"))
Captured output
frame bytes: 15 decoded: Dune,Foundation
  1. Use UTF-8 text containing 中 and recompute byte length.
  2. Advertise a longer body than is sent.
  3. Advertise length 5000 and verify early rejection.
Worked solution

Encode first, then measure len(payload). A truncated body raises EOFError when the peer closes. Length 5000 fails before the body read. Keep worker joins and socket contexts so failing experiments release resources.

9

Lab 2 — HTTP catalogue response

Inspect the JSON body, content type and status. The server binds only locally and shuts down after the checks; http.server is a learning tool rather than a production server.

Download m11_http.py

"""A finite localhost HTTP experiment with JSON, statuses and cleanup."""
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
from threading import Thread
from urllib.error import HTTPError
from urllib.request import urlopen
class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path != "/books":
            self.send_error(404); return
        body = json.dumps([{"id": 1, "title": "Dune"}]).encode("utf-8")
        self.send_response(200)
        self.send_header("Content-Type", "application/json; charset=utf-8")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers(); self.wfile.write(body)
    def log_message(self, *args):
        pass

server = HTTPServer(("127.0.0.1", 0), Handler)
thread = Thread(target=server.serve_forever); thread.start()
try:
    base = f"http://127.0.0.1:{server.server_port}"
    with urlopen(base + "/books", timeout=5) as response:
        books = json.load(response)
        print("GET /books:", response.status, books)
        assert response.status == 200 and books[0]["title"] == "Dune"
    try:
        urlopen(base + "/missing", timeout=5)
    except HTTPError as error:
        print("GET /missing:", error.code); assert error.code == 404; error.close()
    else:
        raise AssertionError("missing resource must be 404")
finally:
    server.shutdown(); server.server_close(); thread.join(timeout=5)
    assert not thread.is_alive()
Captured output
GET /books: 200 [{'id': 1, 'title': 'Dune'}]
GET /missing: 404
  1. Add /health returning a small JSON object.
  2. Return an empty list for an empty catalogue.
  3. Explain why missing paths differ from zero matching books.
Worked solution

A valid /health can return 200 with {'ok':true}. /books with [] is successful 200; /missing is 404 because the resource route does not exist. Keep Content-Length equal to encoded body bytes.

10

Exercises with worked solutions

Try before opening the solution. ★ applies an idea; ★★ combines ideas; ★★★ asks for design or proof.

Exercise 1 — Endpoint★

What distinguishes two services on one IP?

Worked solution

Transport protocol and port, along with the address context.

Exercise 2 — Name versus address★

Can a hostname map to several addresses?

Worked solution

Yes; a name can have multiple address records and answers can change.

Exercise 3 — Partial reads★★

A six-byte body arrives as 2,1,3 bytes. How should the reader behave?

Worked solution

Accumulate until total six; do not decode the incomplete body as a finished message.

Exercise 4 — UTF-8 length★★

What frame length should A中 advertise?

Worked solution

Four bytes, not two code points.

Exercise 5 — Status distinction★★

GET /books returns [] versus GET /unknown. Statuses?

Worked solution

200 for a valid empty collection, 404 for an unknown resource.

Exercise 6 — Retry ambiguity★★★

A borrow POST times out after transmission. Can you assume it failed?

Worked solution

No. The server may have committed while the response was lost. Use a stable request ID and stored result to deduplicate retries.

Exercise 7 — Protocol contract★★★

Specify a bounded text-message format.

Worked solution

Four-byte unsigned big-endian length, maximum 1024 bytes, followed by valid UTF-8. Reject oversized, truncated and invalid-encoding frames. Define whether zero length is valid.

Exercise 8 — Transport versus application★★

Does TCP reliability guarantee a database transaction committed?

Worked solution

No. Transport delivery is different from application validation, execution and commit; the application needs its own response contract.

11

Self-check quiz

Choose an answer for feedback; reset to retry. A text answer key is available without JavaScript.

1

TCP provides?

2

UDP preserves?

3

Length prefixes should count?

4

HTTP 404?

5

TLS replaces authorisation?

6

A timeout proves no server work?

Answer key
  1. A — Application framing is separate.
  2. B — Boundaries are not reliability.
  3. C — The transport carries bytes.
  4. A — It is an application response status.
  5. B — Transport security does not grant access rights.
  6. C — The reply may be lost after work completed.
12

Guided reading

13

Review and the next step

Trace a byte frame and an HTTP response separately. Explain what a timeout does not tell you. Module 12 persists catalogue state in a relational database.

14

Key terms

TermMeaning
FramingIdentifying message boundaries within transported data.
IdempotencyRepeated application has the same intended effect as once.
LoopbackNetworking addressed back to the local host.