Simulate TCP and UDP behaviour
Inject loss, reordering and retransmission into a bounded simulation, then separate transport arrival from application acceptance.

Packet Pat: I want you to trace arrival, ordering, retry and application acceptance as separate decisions.
Predict the reading, then compare it with the measurement.
Python 3 in your browser (JupyterLite)
Python · no installOpen the notebook in your browser and run each Python cell; no install or account is needed.
Three ways to run: use JupyterLite here with no install; run main.py locally from the downloadable lab folder; or open the same notebook in Google Colab.
Steps
Step 1
- Do
- In the JupyterLite notebook, run the Step 1 cell to complete setup and freeze the five-message logical-time experiment.
- You will see
- Input: execute notebook step 1 with the record’s unchanged fixture, seed, and parameters. Observed: seed=42; five messages; logical milliseconds Observed: Browser note: this is a protocol simulation, not an OS socket capture. Observed: Freeze the transport experiment
- Why it matters
- Expected: STEP 1 scenario ready from this deterministic notebook step. Interpretation: Explicit assumptions keep simulated behavior separate from a packet capture. Action: Run the setup and freeze the five-message logical-time experiment. Boundary: this local fixture is not a live device, network, or site measurement.

Step 1 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab) Step 2
- Do
- In the JupyterLite notebook, run the Step 2 cell to inject one UDP loss and one reorder event.
- You will see
- Input: execute notebook step 2 with the record’s unchanged fixture, seed, and parameters. Observed: D1 0 12 ACCEPT Observed: D3 40 58 BUFFER reorder Observed: D2 20 72 ACCEPT late
- Why it matters
- Expected: STEP 2 udp delivered=4 lost=1 reordered=1 from this deterministic notebook step. Interpretation: UDP preserves datagram boundaries but does not promise delivery or order. Action: Inject one UDP loss and one reorder event. Boundary: this local fixture is not a live device, network, or site measurement.

Step 2 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab) Step 3
- Do
- In the JupyterLite notebook, run the Step 3 cell to apply a sequence gate to the UDP arrivals.
- You will see
- Input: execute notebook step 3 with the record’s unchanged fixture, seed, and parameters. Observed: arrival D1 seq=1 -> ACCEPT Observed: arrival D3 seq=3 -> HOLD waiting for seq=2 Observed: arrival D2 seq=2 -> ACCEPT then release D3
- Why it matters
- Expected: STEP 3 udp application-accepted=3 held=1 from this deterministic notebook step. Interpretation: Transport receipt and application acceptance are different events. Action: Apply a sequence gate to the UDP arrivals. Boundary: this local fixture is not a live device, network, or site measurement.

Step 3 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab) Step 4
- Do
- In the JupyterLite notebook, run the Step 4 cell to model TCP recovery of the missing fourth message.
- You will see
- Input: execute notebook step 4 with the record’s unchanged fixture, seed, and parameters. Observed: D1 12 12 Observed: D2 35 35 Observed: D3 48 48
- Why it matters
- Expected: STEP 4 tcp delivered=5 retransmissions=1 from this deterministic notebook step. Interpretation: TCP repairs the ordered byte stream before exposing later bytes. Action: Model TCP recovery of the missing fourth message. Boundary: this local fixture is not a live device, network, or site measurement.

Step 4 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab) Step 5
- Do
- In the JupyterLite notebook, run the Step 5 cell to measure head-of-line delay for D5.
- You will see
- Input: execute notebook step 5 with the record’s unchanged fixture, seed, and parameters. Observed: D5 wire arrival=92 ms Observed: D5 application delivery=140 ms Observed: extra wait=48 ms because D4 was missing
- Why it matters
- Expected: STEP 5 head-of-line delay_ms=48 from this deterministic notebook step. Interpretation: Ordered delivery can add latency even when later bytes already arrived. Action: Measure head-of-line delay for D5. Boundary: this local fixture is not a live device, network, or site measurement.

Step 5 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab) Step 6
- Do
- In the JupyterLite notebook, run the Step 6 cell to perform a bounded CoAP-style confirmable retry.
- You will see
- Input: execute notebook step 6 with the record’s unchanged fixture, seed, and parameters. Observed: 1 0 timeout Observed: 2 110 ACK Observed: message-id=77 is unchanged; receiver duplicate cache prevents two actions.
- Why it matters
- Expected: STEP 6 confirmable attempts=2 actions=1 from this deterministic notebook step. Interpretation: Retry ownership and idempotency are application concerns above UDP. Action: Run a bounded CoAP-style confirmable retry. Boundary: this local fixture is not a live device, network, or site measurement.

Step 6 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab) Step 7
- Do
- In the JupyterLite notebook, run the Step 7 cell to review the model limits and deployment decision.
- You will see
- Input: execute notebook step 7 with the record’s unchanged fixture, seed, and parameters. Observed: UDP: message boundaries remain visible; delivery is not promised. Observed: TCP: ordered stream recovers loss but later bytes may wait. Observed: Decision: choose from workload needs, then test the actual path.
- Why it matters
- Expected: STEP 7 validation PASS from this deterministic notebook step. Interpretation: A simulation explains mechanisms but cannot replace testing the actual path. Action: Review the model limits and deployment decision. Boundary: this local fixture is not a live device, network, or site measurement.

Step 7 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
Chapter checks
These questions refer to the chapter’s examples. Use the return links to review their answers.
A learner says TCP is like a phone call, so the receiver must understand every application message. What should the reviewer clarify?
Return to the chapter’s knowledge checkA cold-room cloud service opens a TCP connection to the gateway and sends a compressor-setpoint command, then claims the compressor accepted the new state. How should reviewers assess the claim that the compressor accepted the command?
Return to the chapter’s knowledge check