# Chat Server

{% hint style="warning" %}
This assignment has automated tests! Make sure to read the [Automated Testing page](https://computer-networks-lab.gitbook.io/computer-networks-lab-manual/course-information/automated-testing) and to download the framework [from GitHub](https://github.com/atlarge-research/cn-lab-student) before starting.
{% endhint %}

### Description

In the chat client assignment, you used a server hosted by the teaching team. This server connects multiple clients and forwards messages between them. In this assignment, you implement your chat server using the same protocol.

Unlike the client, the server is likely to have multiple open connections at the same time—one for each client that is connected to it. Because it is impossible to predict when a client will send a request or message, your server needs to keep checking all connections for incoming data. Both polling and multi-threading are allowed as solutions to this problem.

**Important**: tests will expect a server to start at address 127.0.0.1 and port 5378 (even though you can develop your server using another address and port). The address and port will be, as well, supplied via test script when starting your server script using the `--address` and `--port` . Thus tests will start your server script as `python3 server.py --address "127.0.0.1" --port 5378` . After the server has started and is ready to accept incoming connection the tests will expect a server to output `Server is on` .

### Requirements

Protocol Requirements:

1. **PR1**: Your server must support the full protocol specified in the [Chat Application Protocol](https://computer-networks-lab.gitbook.io/computer-networks-lab-manual/appendix/chat-application-protocol). This is the same protocol as the one used in the Chat Client assignment.
2. **PR2**: Receiving a `HELLO-FROM` message from a user that is not authenticated should trigger an attempt to log the user in with their provided username.
3. **PR3**: If a user logs in with a valid username that is not in use, the server must send a `HELLO` message in response.
4. **PR4**: If a user logs in with an invalid username, the server must send a `BAD-RQST-BODY` message in response and close the connection.
5. **PR5**: If a user logs in with a username that is in use, the server must send an `IN-USE` message as a reply and close the connection.
6. **PR6**: If a user that has already logged in attempts to send a `HELLO-FROM` log-in request, the server must respond with a `BAD-RQST-HDR` message.
7. **PR7**: If a user who has not already logged in attempts to send anything other than a `HELLO-FROM` log-in request, the server must respond with a `BAD-RQST-HDR` message and close the connection.
8. **PR8**: If a logged-in user sends a `LIST` message, the server must reply with a `LIST-OK` message.
9. **PR9**: The body of the `LIST-OK` message must be a comma-separated list, containing only exactly the usernames of all currently logged-in users.
10. **PR10**: If a logged-in user sends a `SEND` message to the server with a valid recipient, the server must send a `DELIVERY` message to the target recipient.
11. **PR11**: If a logged-in user sends a `SEND` message to the server with a valid recipient, and the server forwards it successfully, the server must send a `SEND-OK` message to the original sender.
12. **PR12**: The `SEND-OK` message must not be sent before the corresponding `DELIVERY` a message has been successfully sent.
13. **PR13**: If a logged-in user sends a `SEND` message to the server, where the target recipient is not logged in, the server must respond with a `BAD-DEST-USER` message.
14. **PR14**: If a `SEND` message cannot be forwarded to the specified recipient for any reason, no `SEND-OK` the message must be sent.
15. **PR15**: If a user sends a `HELLO-FROM` message when the server is full, the server must respond with a `BUSY` message.
16. **PR16**: If any error stemming from an invalid message header occurs during operation, other than specified above, the server must send a `BAD-RQST-HDR` message in response.
17. **PR17**: If any error stemming from an invalid message body occurs during an operation, other than specified above, the server must send a `BAD-RQST-BODY` message in response

Username Requirements

1. **UR1**: Usernames must not contain spaces.
2. **UR2**: Usernames must not contain commas.

Technical Requirements:

1. **TR1**: The server must support 16 concurrent users
2. **TR2**: The server must use **Threading** or **Polling** to support concurrent connections.
3. **TR3**: The server must detect when users disconnect and remove them from the logged-in user list.
4. **TR4**: The server must not use *sendall()* function
5. **TR5**: The server must print `Server is on` on startup when ready to start accepting client conenctions.
