Οἱ ἄγγελοι (The messengers) #
The year is 480 B.C.
The Persian king Xerxes (Old Persian: 𐎧𐏁𐎹𐎠𐎾𐏁𐎠, Khshayārsha) has just invaded the Greek city-states.
This unfortunate event has caused many messengers traveling throughout Greece to begin acting as scouts.
They visit a variety of cities. Some settlements are controlled by the Greeks, while others have been taken by the Persians.
To gain an informational advantage, the citizens of Sparta (Doric Greek: Σπάρτα) decide to establish a library connected to the latest telecommunications network for messengers.
Each messenger receives a TCP client application that can connect to the library server.
The library contains a list of city-states and information about whether they are controlled by the Greeks or the Persians.
Each messenger maintains a similar list locally, updating it when new information is received from the central library.
There are 20 city-states. Each one is identified by a number in the range [1, 20].
Your task is to implement a library server compatible with the provided client.
The client program is delivered as a compiled executable. You can run it using:
./client <SERVER_ADDRESS> <PORT_NUMBER>
A compiled executable of a sample server implementation is also provided.
Stages #
Implement handling of a single client connecting to a TCP server.
The server accepts the port number as a command-line argument.
Example server execution:./server 8888
After starting, the server listens for incoming client connections.
Once connected to the first client, it waits to receive 4 bytes of data, prints them to stdout, closes the connection, and then exits.Implement handling of multiple clients and receiving data.
- When a new client connects, they are added to the current list of clients.
- The maximum number of clients is 4.
- If the maximum number of clients is reached, new connections should be rejected.
- Whenever the server receives a 4-byte message from any client, it prints it to the terminal.
Use the epoll function to implement this step
(alternatively, you may use pselect or ppoll).
⚠️ Note: In this step, you do not need to correctly handle client disconnections.
Add to the server an array that stores information about which side each city belongs to.
- Initially, all cities belong to the Greeks.
- Each time the server receives a message in the format:
orpXX\n
wheregXX\n
XX
is a two-digit number representing a city identifier, it indicates that cityXX
now belongs to the Persians or the Greeks, respectively. - If a city’s ownership hasn’t changed, take no action.
- If the city’s owner has changed:
- update the city ownership array,
- broadcast the received message to all other connected clients.
Assumptions:
- You still do not need to handle client disconnections at this stage.
- All incoming messages can be assumed to be in the correct format.
Upon receiving a
SIGINT
signal, the server should:- close all connections,
- print out which side each city belongs to,
- free resources and terminate.
Add proper handling for client disconnections in the following cases:
- Reading from a client descriptor returns a message of length 0.
- Writing to a client descriptor raises an
EPIPE
error. - The message received from the client is not in the correct format or the city number is outside the [1, 20] range.
- The server receives a Control-C (C-c).
⚠️ Note: Disconnected clients free up space for new incoming clients.