Project: reliable delivery
Deliver a report over a lossy radio with packets, acknowledgements and resending.
Do this lesson in the simulatorRadio messages get lost. On a real network, packets are dropped by busy routers and damaged by interference, yet your downloads still arrive perfectly. The trick is in TCP: number every packet, wait for the receiver to say it arrived, and send again if it did not. In this project you build that protocol and use it to get a report safely to the Base robot.
The protocol
The Base follows these rules:
- Every packet is
<number>/<total>:<piece>. - When a packet arrives safely, the Base replies
ack <number>: acknowledged. - When a packet arrives damaged, it replies
resend <number>.
Your robot must follow the rules on its side:
- Send one packet.
- Wait up to one second for a reply.
- If the reply is
ackwith this packet's number, move on to the next packet. - Otherwise, whether the reply was
resendor nothing came at all, send the same packet again.
This is called stop-and-wait: the sender stops after each packet and waits for it to be acknowledged.
Try one packet
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
def wait_reply(seconds=1.0):
for tick in range(int(seconds * 10)):
wait(0.1)
for sender, text in messages():
return text
return None
send("1/3:robot 7 report")
print("the base says:", wait_reply())
send("2/3:ing: mat clear")
print("the base says:", wait_reply())
The second packet was damaged on the way, so the Base asks for it again. Your program has to notice and send it again, however many times it takes.
Plan it first
- a function to split the message into packets (you wrote one in lesson F10.5);
- a loop over the packets;
- inside it, a loop that sends and waits until this packet is acknowledged;
- a count of every transmission, including the ones sent again.
Task: deliver the report
Split message into packets of 14 characters, in the form <number>/<total>:<piece>. Deliver them to the Base with stop-and-wait. Print sent <number> each time you send a packet (including when you send it again) and print each reply you get. Never send the next packet before the last one is acknowledged. When every packet is acknowledged, print delivered in <n> transmissions, and turn the LED green.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
message = "robot 7 reporting: mat clear, battery ok"
Challenges
- Give up after 5 tries of the same packet, and print
failed at packet <n>. - Send all three packets at once, then resend only the ones not acknowledged. How many transmissions does that take?
- Why would a live video call use UDP rather than waiting for acknowledgements?