Final Exam - Practical Part
Distributed Systems and Network Programming - Spring 2023
Task 1 - UDP Socket Programming [8.5 Points]
Write a UDP server and a client using Python socket
module to implement a minimalistic DNS service
- The client sends queries to the server over a UDP socket
- The server replies with a Resource Record (RR) from a predefined list or an error if the record is not found
Client (client.py
)
- Create a
class Query
with two string attributes (type, key
)
- Once started, the client creates the following three
Query
instancesQuery(type="A", key="example.com")
Query(type="PTR", key="1.2.3.4")
Query(type="CNAME", key="moodle.com")
- Serialize the instances using
json
module and send them (one by one) over UDP to the listening server
- Receive and deserialize the server reply, then print the resulting dictionary to the standard output
Server (server.py
)
- Create a
class RR
with three string attributes (type
, key
, value
)
- Once started, the server listens on all interfaces on port
50000
- The server runs forever, unless a
KeyboardInterrupt
is received
- The server maintains a list of resource records. The list initially contains the following two records
RR(type="A", key="example.com", value="1.2.3.4")
RR(type="PTR", key="1.2.3.4", value="example.com")
- Once the server receives a
Query
from a client, it replies with the requested record or an error
- To create an error reply, add
'value': 'NXDOMAIN'
to the received query and send it back to the client
Example Run
$ python3 server.py
Server: listening on 0.0.0.0:50000
Client: {'type': 'A', 'key': 'example.com'}
Server: Record found. Sending answer.
Client: {'type': 'PTR', 'key': '1.2.3.4'}
Server: Record found. Sending answer.
Client: {'type': 'CNAME', 'key': 'moodle.com'}
Server: Record not found. Sending error.
^CServer: Shutting down...
$ python3 client.py
Client: Sending query for example.com
Server: {'type': 'A', 'key': 'example.com', 'value': '1.2.3.4'}
Client: Sending query for 1.2.3.4
Server: {'type': 'PTR', 'key': '1.2.3.4', 'value': 'example.com'}
Client: Sending query for moodle.com
Server: {'type': 'CNAME', 'key': 'moodle.com', 'value': 'NXDOMAIN'}
Task 2 - Remote Procedure Call [8.5 Points]
Write a server and a client to implement a simple remote calculator
- The client calls stub functions to do elementary mathematical operations
- The server executes the corresponding implementations to calculate the required results and send them back to the client
- Communication happens over the local network, with Protocol Buffers as the data serialization format
Server (server.py
)
- Run a gRPC server that listens on all interfaces on port
50000
- The server should run forever unless a
KeyboardInterrupt
is received
- Expose the following functions for RPC. The logic for each function is explained below:
Add(a: int, b: int)
returns a + b
Subtract(a: int, b: int)
returns a - b
Multiply(a: int, b: int)
returns a * b
Divide(a: int, b: int)
returns a / b
or math.nan
if b
equals zero
- Handle remote calls from the client and return the required results
Client (client.py
)
- Once executed, the client calls the following remote functions one by one
Add(10,2)
Subtract(10,2)
Multiply(10,2)
Divide(10,2)
Divide(10,0)
- The client should print the query and the received results, as shown in the example run below
Schema file (calculator.proto
)
Example Run
$ python3 server.py
gRPC server is listening on 0.0.0.0:50000
Add(10,2)
Subtract(10,2)
Multiply(10,2)
Divide(10,2)
Divide(10,0)
^CShutting down...
$ python3 client.py
Add(10,2) = 12.0
Subtract(10,2) = 8.0
Multiply(10,2) = 20.0
Divide(10,2) = 5.0
Divide(10,0) = nan
Final Exam - Practical Part
Task 1 - UDP Socket Programming [8.5 Points]
Write a UDP server and a client using Python
socket
module to implement a minimalistic DNS serviceClient (
client.py
)class Query
with two string attributes (type, key
)Query
instancesQuery(type="A", key="example.com") Query(type="PTR", key="1.2.3.4") Query(type="CNAME", key="moodle.com")
json
module and send them (one by one) over UDP to the listening serverServer (
server.py
)class RR
with three string attributes (type
,key
,value
)50000
KeyboardInterrupt
is receivedRR(type="A", key="example.com", value="1.2.3.4") RR(type="PTR", key="1.2.3.4", value="example.com")
Query
from a client, it replies with the requested record or an error'value': 'NXDOMAIN'
to the received query and send it back to the clientExample Run
$ python3 server.py Server: listening on 0.0.0.0:50000 Client: {'type': 'A', 'key': 'example.com'} Server: Record found. Sending answer. Client: {'type': 'PTR', 'key': '1.2.3.4'} Server: Record found. Sending answer. Client: {'type': 'CNAME', 'key': 'moodle.com'} Server: Record not found. Sending error. ^CServer: Shutting down...
$ python3 client.py Client: Sending query for example.com Server: {'type': 'A', 'key': 'example.com', 'value': '1.2.3.4'} Client: Sending query for 1.2.3.4 Server: {'type': 'PTR', 'key': '1.2.3.4', 'value': 'example.com'} Client: Sending query for moodle.com Server: {'type': 'CNAME', 'key': 'moodle.com', 'value': 'NXDOMAIN'}
Task 2 - Remote Procedure Call [8.5 Points]
Write a server and a client to implement a simple remote calculator
Server (
server.py
)50000
KeyboardInterrupt
is receivedAdd(a: int, b: int)
returnsa + b
Subtract(a: int, b: int)
returnsa - b
Multiply(a: int, b: int)
returnsa * b
Divide(a: int, b: int)
returnsa / b
ormath.nan
ifb
equals zeroClient (
client.py
)Add(10,2) Subtract(10,2) Multiply(10,2) Divide(10,2) Divide(10,0)
Schema file (
calculator.proto
)service
with remote functions that can be called throughrpc
message
types for the client/server communicationgrpcio
andgrpcio-tools
installed. You may use a virtual environment if needed.proto
file using the following commandExample Run