1. protocol.py

This file defines the message formats and provides utility functions for creating and parsing protocol messages used in both client-server and peer-to-peer communication.

FunctionDescriptionImportance
parse_register(msg)Parses a REGISTER message string.Extracts nickname and udp_port from the raw message. Returns None if malformed. Essential for server to process client registrations.
make_joined(nickname, ip, udp_port, tcp_port)Creates a JOINED message string.Used by the server to inform clients when a new peer (including themselves) has joined the chat, providing their network details.
make_left(nickname)Creates a LEFT message string.Used by the server to inform clients when a peer has disconnected.
make_broadcast(message)Creates a BROADCAST message string.Used by clients to send a message that the server should relay to all other connected clients.
parse_port(msg)Parses a PORT message string.Extracts nickname and tcp_port from the raw message. Used by the server to get the client’s TCP port for peer-to-peer connections.
make_port(nickname, tcp_port)Creates a PORT message string.Used by clients to inform the server of their TCP port for peer-to-peer connections, sent after REGISTER.
make_chat_request(nickname)Creates a CHAT_REQUEST message string.Used by a client to initiate a peer-to-peer chat session with another client.
is_chat_request(msg)Checks if a message string is a CHAT_REQUEST.Helper to identify incoming chat requests.
parse_chat_request(msg)Parses a CHAT_REQUEST message string.Extracts the requesting nickname. Returns None if malformed.
make_chat_accept(nickname)Creates a CHAT_ACCEPT message string.Used by a client to accept an incoming peer-to-peer chat request.
is_chat_accept(msg)Checks if a message string is a CHAT_ACCEPT.Helper to identify incoming chat acceptances.
parse_chat_accept(msg)Parses a CHAT_ACCEPT message string.Extracts the accepting nickname. Returns None if malformed.
make_chat_reject(nickname)Creates a CHAT_REJECT message string.Used by a client to reject an incoming peer-to-peer chat request.
is_chat_reject(msg)Checks if a message string is a CHAT_REJECT.Helper to identify incoming chat rejections.
parse_chat_reject(msg)Parses a CHAT_REJECT message string.Extracts the rejecting nickname. Returns None if malformed.
make_left_chat(nickname)Creates a LEFT_CHAT message string.Used by a client to inform a peer that they are leaving the current peer-to-peer chat session.
is_left_chat(msg)Checks if a message string is a LEFT_CHAT.Helper to identify when a peer has left a chat session.
parse_left_chat(msg)Parses a LEFT_CHAT message string.Extracts the nickname of the peer who left. Returns None if malformed.
make_chat_msg(nickname, message)Creates a CHAT_MSG message string.Used by clients to send an actual chat message text to a connected peer during a peer-to-peer session.
is_chat_msg(msg)Checks if a message string is a CHAT_MSG.Helper to identify incoming peer-to-peer chat messages.
parse_chat_msg(msg)Parses a CHAT_MSG message string.Extracts the sender’s nickname and the message content. Returns None if malformed.
make_error(reason)Creates an ERROR message string.Used by both server and clients to signal a protocol error or unexpected situation, providing a reason.
is_error(msg)Checks if a message string is an ERROR.Helper to identify incoming error messages.
parse_error(msg)Parses an ERROR message string.Extracts the reason for the error. Returns None if malformed.
make_nickname_taken()Creates a NICKNAME_TAKEN message string.Used by the server to inform a client that their chosen nickname is already in use.
is_nickname_taken(msg)Checks if a message string is NICKNAME_TAKEN.Helper for the client to identify if their registration was rejected due to a nickname conflict.

2. tcp.py

This file handles the low-level TCP communication, specifically message framing by prefixing messages with their length.

FunctionDescriptionImportance
recv_all(conn, length)Receives exactly length bytes from the socket conn.Ensures that the complete message (or length prefix) is read, handling cases where TCP packets might be fragmented. Crucial for reliable message boundary detection.
recv_message(conn)Receives a complete message from the socket conn.First, it reads a 10-byte length prefix, decodes it to get the message length, then calls recv_all to read the actual message content. Decodes the message to a string.
send_message(conn, msg)Sends a message string over the socket conn.Encodes the message to bytes, prepends a 10-byte length prefix (left-padded with spaces), and sends both the prefix and the message. Ensures the receiver can delimit messages.

3. udp.py

This file handles UDP communication, providing functions to listen for UDP messages and send them.

FunctionDescriptionImportance
listen_for_udp(port, on_message)Starts a UDP server in a daemon thread to listen for incoming messages on the specified port.When a message is received, it calls the on_message callback with the message data and sender’s address. Used by clients for peer discovery or direct UDP messages.
send_udp(target_ip, target_port, message)Sends a UDP message to the specified target_ip and target_port.Encodes the message string to bytes before sending. Used for sending UDP messages, like peer discovery pings or direct UDP chat (if implemented).

4. core.py (Server class)

This file contains the main logic for the PeerChat server.

MethodDescriptionImportance
init(host, port)Initializes the server with the host and port to listen on. Sets up clients dictionary and a lock for thread safety.Basic setup for the server instance.
broadcast(msg, exclude_nick)Sends a message to all connected clients, optionally excluding one client by exclude_nick.Core server functionality for relaying messages (like JOINED, LEFT, BROADCAST) to all relevant clients. Uses the lock to safely iterate over the clients dictionary.
handle_client(conn, addr)Manages a single client connection from registration through the message loop.This is the main entry point for a new client. It handles the initial REGISTER and PORT message sequence, nickname conflicts, and then hands off to _client_message_loop. It also handles client disconnection and cleanup.
_client_message_loop(conn, nickname)Processes messages from a connected and registered client.Handles ongoing communication with a client after successful registration. It processes BROADCAST and PORT (update) messages. It enforces protocol rules (e.g., client cannot send JOINED or ERROR).
start()Starts the main server loop, listening for incoming client connections.Binds to the host/port and accepts new connections, spawning a new thread running handle_client for each. Includes try-except for graceful shutdown on KeyboardInterrupt and prints status messages.
_cleanup_client(conn, nickname)(Implicit within handle_client’s finally block) Removes a client from the clients list and broadcasts a LEFT message.Ensures proper state management when a client disconnects or an error occurs.

5. core.py (Client class)

This file contains the main logic for the PeerChat client.

MethodDescriptionImportance
init(server_ip, server_port, nickname, udp_port, tcp_port)Initializes the client with server details, user’s nickname, and network ports.Basic setup for the client instance, including state variables for peer connections, callbacks, etc.
set_callbacks(**kwargs)Allows the GUI (or other frontends) to register callback functions for various client events (e.g., on_message, on_peer_joined).Decouples the client core logic from the UI. The core logic calls these callbacks to update the UI or notify about events.
_cb(name, *args, **kwargs)Internal helper to safely invoke a registered callback by its name.Prevents errors if a callback is not set and simplifies calling callbacks.
register()Connects to the server and sends REGISTER and PORT messages. Starts _listen_to_server thread.Initiates the client’s session with the server. Handles potential connection or registration errors.
_listen_to_server()Listens for messages from the server (e.g., JOINED, LEFT, BROADCAST, ERROR, NICKNAME_TAKEN) and processes them.Handles all server-to-client communication after registration. Updates internal peer list and triggers UI callbacks.
start_peer_server(tcp_port)Starts a TCP server socket to listen for incoming peer-to-peer chat connection requests.Allows other clients to initiate direct TCP connections for P2P chat. Each incoming connection is handled in a new thread by _handle_peer_connection.
_handle_peer_connection(conn, addr)Manages an incoming peer-to-peer TCP connection, listening for messages from that peer.Dedicated loop for receiving messages from a single connected peer. Passes messages to _handle_peer_message.
send_tcp_to_peer(peer_ip, peer_port)Initiates a TCP connection to another peer and sends a CHAT_REQUEST.Starts the P2P chat process from the initiator’s side. Handles connection timeouts and errors.
send_message_to_peer(addr, message)Sends a CHAT_MSG to an already connected peer.Used to send actual chat text during an active P2P session.
close_chat(addr)Closes an active peer-to-peer chat session, sending LEFT_CHAT to the peer.Gracefully ends a P2P chat.
get_peer_nickname(addr)Retrieves the nickname associated with a peer’s address.Utility for displaying peer information.
_handle_peer_message(addr, msg, sock)Processes incoming messages from a peer (e.g., CHAT_REQUEST, CHAT_ACCEPT, CHAT_REJECT, LEFT_CHAT, CHAT_MSG, ERROR).Core logic for P2P communication. It manages chat session states (request, accept, reject), handles chat messages, and processes errors or disconnections. Includes timeout logic for chat requests.
start_udp_listener(on_message)Starts a UDP listener using network.udp.listen_for_udp.Allows the client to receive UDP messages, typically for peer discovery or other UDP-based features. The on_message callback (often _handle_udp_message) processes these.
_handle_udp_message(data, addr)(If implemented and connected to start_udp_listener) Processes incoming UDP messages.Placeholder or actual handler for UDP messages. Could be used for peer discovery responses or direct UDP chat.
shutdown()Gracefully shuts down the client, closing server and peer connections.Ensures resources are released and threads are stopped cleanly.