Distributed Systems and Network Programming - Spring 2023
Task
Your task for this lab is to write a UDP server using Python socket module that communicates with a given client. The client reads a file from the local file system and uploads it to the server.
Client Implementation
The client starts by sending the following string message s|0|filename.ext|filesize where:
s indicates that the message type is start
| is the field delimiter.
0 is the initial sequence number.
filename.ext is the name of the file to be sent (with extension).
filesize is the total size of the file to be sent in bytes.
The client expects a reply from the server in the format a|seqno where:
a indicates that the message type is acknowledgement.
seqno equals (x+1)%2 where x is the sequence number of the message to be acknowledged.
If the expected server acknowledgement was received successfully, the client does the following:
Divide the file into chunks so that the size of a single data packet (including headers) does not exceed the buffer size of the server.
Start sending file chunks, one by one. Each message has the format d|seqno|data where:
d indicates that the message type is data
seqno is the sequence number of the data message, it alternates between 1 and 0, starting from 1.
data is the raw bytes of the file.
The client waits for an acknowledgement message after sending each chunk.
If an expected acknowledgement message does not arrive within 1 second, the client retransmits the message.
If an acknowledgement message arrives with an unexpected sequence number, the client ignores that duplicate ACK and keeps waiting for the expected ACK.
Server Implementation (your task)
Parse one integer argument, the port number to listen on.
Create a UDP socket and start listening for incoming messages on 0.0.0.0:<port>.
The server should use a fixed receiver buffer size of 20480 bytes (20 Kibibytes).
Upon receiving a message from a client, inspect the message type (first character).
If the message type is s, prepare to receive a file from the client with the given name and size.
If the message type is d, write the delivered chunk to the file system.
Otherwise, terminate gracefully with an error.
In both cases, reply with an acknowledge message in the format a|seqno where
a indicates that the message type is acknowledgement.
seqno equals (x+1)%2 where x is the sequence number of the message to be acknowledged.
Once the file is received completely, the server should print an indicating message, write the content to the file system, and close the file.
If an existing file with the same name is present in the server directory, the server should print an indicating message and overwrite that file with the new one.
Your server will be tested under constant delay and packet loss. The following Linux command can be used to simulate 15% packet loss and 1100 milliseconds constant delay over the lo interface. File transfer should still succeed after applying the command. To undo the effect use del instead of add.
sudo tc qdisc add dev lo root netem loss 15% delay 1100ms
The server stays running unless a fatal error occurs or a KeyboardInterrupt is received.
Your submitted code should satisfy the following requirements. Failing to satisfy an item will result in partial grade deduction or an assignment failure (depending on the severity).
One submitted source file named according to the format NameSurname.py
Week 1 - Stop-and-Wait ARQ
Task
Client Implementation
s|0|filename.ext|filesize
where:s
indicates that the message type isstart
|
is the field delimiter.0
is the initial sequence number.filename.ext
is the name of the file to be sent (with extension).filesize
is the total size of the file to be sent in bytes.a|seqno
where:a
indicates that the message type isacknowledgement
.seqno
equals(x+1)%2
wherex
is the sequence number of the message to be acknowledged.d|seqno|data
where:d
indicates that the message type isdata
seqno
is the sequence number of the data message, it alternates between1
and0
, starting from1
.data
is the raw bytes of the file.Server Implementation (your task)
0.0.0.0:<port>
.20480
bytes (20 Kibibytes).s
, prepare to receive a file from the client with the given name and size.d
, write the delivered chunk to the file system.a|seqno
wherea
indicates that the message type isacknowledgement
.seqno
equals(x+1)%2
wherex
is the sequence number of the message to be acknowledged.lo
interface. File transfer should still succeed after applying the command. To undo the effect usedel
instead ofadd
.KeyboardInterrupt
is received.Testing
The project structure looks like this
Example run and output
$ python3 NameSurname.py 8080 ('0.0.0.0', 8080): Listening... ('127.0.0.1', 48256): s|0|note.txt|446 ('127.0.0.1', 48256): d|1|chunk1 ('0.0.0.0', 8080): Received note.txt. ^C('0.0.0.0', 8080): Shutting down...
$ cd client $ python3 client.py 127.0.0.1:8080 note.txt Client: s|0|note.txt|446 Server: a|1 Client: d|1|chunk1 Server: a|0
Example session visualization
Resulting directory structure. The text file should arrive intact.
Checklist
Your submitted code should satisfy the following requirements. Failing to satisfy an item will result in partial grade deduction or an assignment failure (depending on the severity).
NameSurname.py