Create Chat App in Python
Create Chat App in Python
multiple clients, and potentially providing a user interface. Here are a few approaches, ranging
from a simple command-line chat to a more feature-rich GUI application:
1. Simple Command-Line Chat (TCP Socket)
This is the most basic approach to understand the underlying networking concepts.
Server (server.py):
import socket
import threading
HOST = '127.0.0.1' # Standard loopback interface address (localhost)
PORT = 65432 # Port to listen on (non-privileged ports are >
1023)
clients = []
nicknames = []
def broadcast(message):
for client in clients:
try:
client.send(message.encode('utf-8'))
except:
remove(client)
def handle_client(client):
while True:
try:
message = client.recv(1024).decode('utf-8')
broadcast(f"{nicknames[clients.index(client)]}:
{message}".encode('utf-8'))
except:
index = clients.index(client)
nickname = nicknames[index]
remove(client)
broadcast(f'{nickname} left the chat!'.encode('utf-8'))
break
def remove(client):
if client in clients:
index = clients.index(client)
clients.remove(client)
nicknames.pop(index)
def receive():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen()
print(f"Server listening on {HOST}:{PORT}")
while True:
client, address = server.accept()
print(f"Connected with {str(address)}")
client.send('NICK'.encode('utf-8'))
nickname = client.recv(1024).decode('utf-8')
nicknames.append(nickname)
clients.append(client)
print(f"Nickname of the client is {nickname}!")
broadcast(f'{nickname} joined the chat!'.encode('utf-8'))
client.send('Connected to the server!'.encode('utf-8'))
thread = threading.Thread(target=handle_client,
args=(client,))
thread.start()
if __name__ == "__main__":
receive()
Client (client.py):
import socket
import threading
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 65432 # The port used by the server
nickname = input("Choose your nickname: ")
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client.connect((HOST, PORT))
except socket.error as e:
print(f"Connection error: {e}")
exit()
def receive():
while True:
try:
message = client.recv(1024).decode('utf-8')
if message == 'NICK':
client.send(nickname.encode('utf-8'))
else:
print(message)
except:
print("Error occurred!")
client.close()
break
def write():
while True:
message = f'{input("")}'
client.send(message.encode('utf-8'))
receive_thread = threading.Thread(target=receive)
receive_thread.start()
write_thread = threading.Thread(target=write)
write_thread.start()
How to Run:
1. Save the server code as server.py and the client code as client.py.
2. Open a terminal or command prompt and run the server: python server.py
3. Open multiple other terminals or command prompts and run the client for each user:
python client.py
4. Each client will be prompted to enter a nickname. After that, they can start sending
messages.
2. GUI Chat Application (Tkinter)
For a graphical user interface, you can use libraries like Tkinter (built-in) or PyQt/PySide. Here's
a basic example using Tkinter:
import tkinter as tk
from tkinter import scrolledtext, simpledialog, messagebox
import socket
import threading
HOST = '127.0.0.1'
PORT = 65432
class ChatClient:
def __init__(self, master):
self.master = master
master.title("Chat Client")
self.nickname = simpledialog.askstring("Nickname", "Choose
your nickname:", parent=self.master)
if not self.nickname:
self.master.destroy()
return
self.chat_area = scrolledtext.ScrolledText(master, width=60,
height=20, state=tk.DISABLED)
self.chat_area.pack(padx=10, pady=10)
self.message_entry = tk.Entry(master, width=50)
self.message_entry.pack(padx=10, pady=5)
self.message_entry.bind("<Return>", self.send_message)
self.send_button = tk.Button(master, text="Send",
command=self.send_message)
self.send_button.pack(pady=5)
self.client_socket = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
try:
self.client_socket.connect((HOST, PORT))
self.receive_thread =
threading.Thread(target=self.receive)
self.receive_thread.start()
self.client_socket.send(self.nickname.encode('utf-8')) #
Send nickname after connecting
except socket.error as e:
messagebox.showerror("Connection Error", f"Could not
connect to server: {e}")
self.master.destroy()
def receive(self):
while True:
try:
message =
self.client_socket.recv(1024).decode('utf-8')
self.chat_area.config(state=tk.NORMAL)
self.chat_area.insert(tk.END, message + '\n')
self.chat_area.config(state=tk.DISABLED)
self.chat_area.see(tk.END)
except:
messagebox.showerror("Error", "Connection to server
lost!")
self.client_socket.close()
self.master.destroy()
break
def send_message(self, event=None):
message = self.message_entry.get()
self.message_entry.delete(0, tk.END)
try:
self.client_socket.send(message.encode('utf-8'))
except socket.error as e:
messagebox.showerror("Send Error", f"Could not send
message: {e}")
if __name__ == "__main__":
server_thread = threading.Thread(target=lambda:
exec(open("server.py").read()))
server_thread.daemon = True # Allow the main script to exit even
if the server thread is running
server_thread.start()
root = tk.Tk()
client_app = ChatClient(root)
root.mainloop()
Key Concepts:
● Sockets: The fundamental building blocks for network communication.
● Server: Listens for incoming connections from clients.
● Client: Initiates a connection to the server.
● IP Address and Port: Used to identify the server and the specific application on the
server.
● TCP (Transmission Control Protocol): A reliable, connection-oriented protocol used for
most chat applications.
● Threading/Asyncio: Used to handle multiple client connections concurrently without
blocking.
● GUI Framework (Tkinter, PyQt): For creating a graphical user interface.
● Broadcasting: Sending a message to all connected clients.
Further Enhancements:
● User Interface: Create a more user-friendly GUI with features like displaying user lists,
private messaging, etc.
● Message Formatting: Implement formatting options (bold, italics, etc.).
● User Authentication: Add a login system.
● Room/Channel Support: Allow users to join different chat rooms.
● File Transfer: Enable users to send files to each other.
● Error Handling: Implement more robust error handling for network issues.
Choose the approach that best suits your needs and complexity requirements. The
command-line chat is a good starting point to understand the basics, while a GUI application
provides a better user experience. Asynchronous frameworks are recommended for building
more scalable and efficient chat servers.