Changelog:
- 28 August 2025: fix bug in
test.py’s parsing for thesendcommand where it only read the first byte in the hex or binary formats
If you downloaded the skeleton code before 28 August 2025 around 9:30pm, the
test.pyhad a bug in thesendcommand; you can download an updated version of test.py here.
1 Your Task
Download the supplied skeleton code at here.1 (last update 28 August 2025)
In
sendrecv.pycomplete an implementation of MySender and MyReceiver.In MySender’s
send_messagefunction, receive a message in bytes, then format a message to be sent as a sequence of bits, then callself.channel.send_bits()with those bytes.In MyReceiver’s
handle_bit_from_networkfunction, receive a bit from the network, then callself.got_message_function()when those bytes represent a full message passed toMySender’ssend_messagefunction.To demonstrate the interface, we supply an example implementation which is partially functional. It transmits messages by converting each byte into bits, and adding a nul byte to separate messages. This satisfies some but not all of the requirements below.
Your implementation must:
Be able to send messages of any length between 0 and 1023 bytes, inclusive
Allow messages to contain any sequence of bytes (of an appropriate length).
(This means that, for example, we should be able to take some of the bits your
send_messagefunction produces and send a new message containing them without it being corrupted.)If a message’s bytes are corrupted, by changing the values of bits randomly and/or adding and removing bits randomly, then:
You should detect this and avoid calling
got_message_functionwith data that does not represent a valid message at least 99.99% of the time. You should be able to achieve this with a 2 or more-byte checksum.Other than possibly the next few messages or couple kilobytes of messages, future uncorrupted messages should be received correctly (regardless of where the corruption took place).
Not use too much space to send messages:
- Including any headers/separators, the average size of a random message of N bytes at most 120 bytes or N * 1.2 bytes, whichever is larger. (It’s okay if some pathological messages take up more space.)
Be your own code and use only functionality built-in to python or supplied as part of its standard library. This means that it is permissible to use the
zlibmodule’scrc32function and thehashlibmodule and thestructmodule. But it is not permissible to use, for example, python-pppd
Test your implementation using
test.py:If you downloaded
test.pybefore 28 August 2025 around 9:30pm, you should get an updated test.py to fix a bug with reading hex/binary input forsend.You can use
python3 test.py send ...to send sample messages:python3 test.py send --input-format binary --output-format binary 00001111 11110000 python3 test.py send --input-format hex --output-format hex FF00FF00 809080908090You can use
python3 test.py recv ...to receive bits:python3 test.py recv --input-format binary --output-format binary 111100011110000111111 python3 test.py recv --input-format hex --output-format hex FF00FFFFFFFYou can use
python3 test.py suite ...to run a test suite:python3 test.py suite python3 test.py suite --verboseYou can specify to only run parts of test suites by passing a regular expression to –only-test and/or –only-subtest:
python3 test.py suite --only-test=empty-clean python3 test.py suite --only-test=tiny.* python3 test.py suite --only-test=corrupt-first-recovery-tiny1 --only-subtest='delete bit #.*' python3 test.py suite --only-test=corrupt-first-recovery-tiny1 --only-subtest='delete bit #2'
If you want to run additional tests, you might find it useful to modify the list of tests in
TESTS.When grading, we may run additional tests and/or inspect your code by hand. Although the supplied tests do not intentionally omit functionality you must implement, they may get
unlucky
and fail to detect an implementation which is actually broken and they do not test everything for all possible message sizes. (Also, because some requirements deal with chances of corruption, it may be possible for them to spuriously fail on a correct implementation, though I think that is unlikely.)Briefly document in a comment or docstring near the top of your
sendrecv.pythe frame format you choose.Submit your
sendrecv.pyby using the submission site.
2 Hints
You can reuse the supplied bit to byte and byte to bit conversions..
The
structmodulespackorunpackto convert integers to bytes and vice-versa.Be careful about choosing ambiguous message delimters.
For example, let’s say you choose 0000 as a delimiter for messages and to escape 000 with 0001 and we try to send the message 111111100.
In this case, we’ll send 111111100 0000. There was no reason to escape anything. When we try to remove the delimiter from this, we’ll find the first 0000, and get 1111111, which is not our original message.
The problem here is that the escaping is not sufficient to handle the end-of-message edge case. We could fix this by escaping every 0 instead of every 000, but that’s pretty inefficient. A more space-efficient solution is to choose a delimiter pattern that has a distinctive transition from 0s to 1s that allows us to escape less frequently. The choice of 010 in lecture and 01111110 in the textbook (Systems Approach section 2.3) are examples of this.
If you want to work on portal or similar, you might find it useful to right-click the link, select
copy link
orcopy URL
from the drop-down menu, then run the commandwget THAT_URL, whereTHAT_URLis the result of pasting the link/URL.↩︎