Changelog:

  • 27 Oct 2023: update netlab.tar’s libnetsim.a to support waitForAllTimeouts() being called multiple times; also adjust make flags some
  • 30 Oct 2023: be more explicit that number after GET selects which message to retrieve and that this is is filled in from the command line by the supplied code
  • 30 Oct 2023: fix bug where simulator would mishandle clearTimeout() of a currently active callback; adjust supplied code to not print out extra NULs
  • 31 Oct 2023: be more explicit about checkoff requirements
  • 31 Oct 2023: update netlab.tar to make ./netlab 0 (not required for lab) avoids sending duplicate messages for single ACKs
  • 1 Nov 2023: be more explicit that waitForAllTimeouts is what calls recvd and timeout callbacks; mention that it needs to run in Sleep example
  • 2 Nov 2023: explicitly state that acknowledging the previous message requests the next one be sent/resent

You’ve already worked with TCP sockets in CSO1. In this lab you’ll learn how to add reliability on top of unreliable mailbox type model of a network.

You’ll have enough to do in this lab, we’ll not worry about doing it over an actual network. We’ve provided a simple network simulator for you.

Possibly working with a partner —

  1. Download netlab.tar [last updated 31 Oct] on a linux system (e.g., with wget https://www.cs.virginia.edu/~cr4bd/3130/F2023/files/netlab.tar).

  2. Extract it and enter the directory (e.g., with tar xvf netlab.tar; cd netlab).

  3. Test it with

    make
    ./netlab 0

    You should see a welcome message appear, ending with a !.

  4. Edit netlab.c so that you also see messages for ./netlab 1, ./netlab 2, etc. See below for a description of the messages the (simulated) server you are communicating with expects, including when you need to send acknowledgment or resend requests if you don’t receive a response.

  5. Show a TA your code or submit it to the submission site.

    • To get full credit for checkoff, you should finish ./netlab 1 and show significant progress on ./netlab 2. (We’d like you to complete ./netlab 2 if you’re able to in the lab time, but we intend to give credit if you make a significant attempt but don’t manage.)
    • ./netlab 3 is quite a bit harder and is recommended if you have time, but not required for checkoff/submission
    • If you are submitting instead of checking off, we require ./netlab 1 and ./netlab 2 to be complete

1 Our Driver

We provide a network simulation driver program. It has the following pieces:

2 Protocol

Every message must have its first byte be a checksum. We’ll use a very simple checksum for this lab: the xor of all other bytes.

To send the array of bytes [0, 1, 2, 5] you actually send a five-byte message: [0^1^2^5, 0, 1, 2, 5].

You should send the server a 4-byte message (plus a checksum) to initiate conversation. The first three bytes should be the ASCII characters for GET; the fourth should be an ASCII digit 0 through 9. The ASCII digit selects which message to retrieve (higher numbered messages are more difficult to handle), and is filled in from the command line argument in our supplied code. The server will then start sending you messages in discrete packets.

The first three bytes of each packet the server sends will be a checksum, a (1-based) sequence number, and the total sequence count. Both sequence number and sequence count will be encoded directly as a byte, not using ASCII.

If the server plans to send two packets, one containing [3, 1] and the other [4, 1, 5], they will actually arrive as [1^2^3^1, 1, 2, 3, 1] and [2^2^4^1^5, 2, 2, 4, 1, 5].

After receiving a message, you should reply with a four-byte message (plus a checksum) to acknowledge it and request the next message. The first three bytes should be the ASCII characters for ACK; the fourth should be the sequence number you received. If the next message is not delivered, you should reply with the ACK of the last message you got in order (or re-send the GET if the very first message is not delivered) to request the next message be resent. However, messages may be delayed in transit and may arrive out of order. You should wait at least a few seconds before deciding a message will not arrive and re-sending its request.

Each GET will give a different message, and with a different level of errors you need to handle.

  1. sends the full message without errors
  2. sends the full message without errors, one a packet at a time, requiring you to ACK properly
  3. sends messages unreliably; some messages never arrive and need to be re-requested
  4. sends messages unreliably; some messages arrive in a corrupted state and need to be re-requested

You may assume that if a message has not arrived after a full second, it will not arrive.

3 Tips

3.1 How the protocol works

3.2 Using setTimeout