### Exercise Sheet: Implementing a UDP Broadcast Chat Client
#### Context:
In this exercise, you will implement a UDP Broadcast Chat Client using Python. The chat client allows users to send and receive messages in real-time. The client is designed with a graphical user interface (GUI) using Tkinter. You will complete the implementation by filling in the missing parts of the program.
### Background on UDP and Broadcasts:
UDP (User Datagram Protocol) is a connectionless protocol that allows sending messages without establishing a connection. It is suitable for applications that need fast, efficient transmission, such as real-time communication. Broadcasting, on the other hand, sends a message to all devices on a local network. UDP broadcasts use a special IP address (`255.255.255.255`) to ensure that the message is delivered to all devices in the subnet.
### Tasks:
#### Task 1 (T1): Initialize the UDP Socket and Handle Incoming Messages
In this task, you will set up the UDP socket and ensure the client can receive messages. First, you need to initialize `self.sock` as a UDP socket. This involves creating a socket that can communicate over the network using UDP. You also need to configure this socket to enable broadcast messages and allow the port to be reused quickly. Once the socket is set up, implement the logic to receive messages from it. Use the `recvfrom` method to receive messages, then parse these messages to extract the sender's nickname and the message content. Finally, display the received messages in the chat window using the `self.print()` method.
#### Task 2 (T2): Broadcast Messages to Other Clients
The objective of this task is to enable the client to send broadcast messages to other clients. Implement the functionality to send messages as broadcasts to all clients in the network. Ensure that the messages are encoded as byte arrays before sending them. Use the socket's `sendto` method to broadcast these messages. This task ensures that all clients can communicate with each other by broadcasting their messages to the entire network.
#### Task 3 (T3): Manage and Update the Buddy List
In this task, you will maintain a list of connected peers and update the GUI accordingly. Start by keeping a record of peers who send messages, including their nicknames, addresses, and timeout values. This record should be updated whenever a message is received. Additionally, periodically send keepalive messages to inform other clients that your client is still active. Schedule the `event_tick` method to run periodically, decrementing the timeout values and removing stale peers. Finally, refresh the buddy list in the GUI to display the current list of connected peers, ensuring that the buddy list accurately reflects the active users.
#### Task 4 (T4): Implement Direct Messages
The final task is to enable sending direct messages to specific clients. Implement the ability to send a message directly to a specific client by typing "NICK: MESSAGE". This involves checking if the message contains a colon (":") to identify it as a direct message. Then, look up the recipient's address in the peer list and send the message directly to that specific address. This task ensures that users can have private conversations with specific peers, in addition to broadcasting messages to the entire network.
By completing these tasks, you will gain experience in working with UDP sockets, handling real-time communication, and managing a GUI application in Python. Happy coding!