Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
2 views

Create Chat App in Python

The document provides a comprehensive guide on creating a chat application in Python, detailing three approaches: a simple command-line chat using TCP sockets, a GUI chat application using Tkinter, and an asynchronous chat application using asyncio. It includes code examples for both server and client implementations, as well as instructions on how to run each version. Key concepts such as sockets, server-client architecture, and threading are explained, along with suggestions for further enhancements to improve the application.

Uploaded by

alzienabo
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Create Chat App in Python

The document provides a comprehensive guide on creating a chat application in Python, detailing three approaches: a simple command-line chat using TCP sockets, a GUI chat application using Tkinter, and an asynchronous chat application using asyncio. It includes code examples for both server and client implementations, as well as instructions on how to run each version. Key concepts such as sockets, server-client architecture, and threading are explained, along with suggestions for further enhancements to improve the application.

Uploaded by

alzienabo
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

Creating a chat application in Python involves handling network communication, managing

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()​

To Run the GUI Chat:


1.​ Save the server code as server.py (same as the command-line version).
2.​ Save the GUI client code as another Python file (e.g., client_gui.py).
3.​ Run the GUI client: python client_gui.py
4.​ The server will automatically start in a separate thread (for simplicity in this example).
Multiple instances of the GUI client can connect.
3. Using a Framework (e.g., Twisted, Asyncio)
For more scalable and robust network applications, consider using asynchronous frameworks
like Twisted or Asyncio. These frameworks handle network events in a non-blocking way,
allowing the server to handle many connections efficiently.
Here's a very basic outline using asyncio:
Asyncio Server (async_server.py):
import asyncio​

async def handle_client(reader, writer):​
addr = writer.get_extra_info('peername')​
print(f"Connected by {addr}")​

try:​
nickname = (await reader.read(1024)).decode('utf-8').strip()​
print(f"Client {addr} nickname: {nickname}")​
# Store nickname and writer for broadcasting​

while True:​
data = await reader.read(1024)​
if not data:​
break​
message = data.decode('utf-8').strip()​
print(f"Received from {nickname}: {message}")​
# Broadcast the message to all other clients​

except asyncio.CancelledError:​
print(f"Client {addr} disconnected.")​
except ConnectionResetError:​
print(f"Client {addr} forcibly disconnected.")​
finally:​
writer.close()​
# Remove client from the list​

async def main():​
server = await asyncio.start_server(​
handle_client, '127.0.0.1', 65432​
)​

addrs = ', '.join(str(sock.getsockname()) for sock in
server.sockets)​
print(f'Serving on {addrs}')​

async with server:​
await server.serve_forever()​

if __name__ == "__main__":​
asyncio.run(main())​

Asyncio Client (async_client.py):


import asyncio​

async def main():​
reader, writer = await asyncio.open_connection('127.0.0.1', 65432)​

nickname = input("Choose your nickname: ")​
writer.write(nickname.encode('utf-8'))​
await writer.drain()​

async def receive():​
while True:​
try:​
data = await reader.read(1024)​
if not data:​
break​
print(data.decode('utf-8').strip())​
except ConnectionResetError:​
print("Connection to server lost.")​
break​

async def send():​
while True:​
message = input()​
writer.write(message.encode('utf-8'))​
await writer.drain()​

receive_task = asyncio.create_task(receive())​
send_task = asyncio.create_task(send())​

await asyncio.gather(receive_task, send_task)​

writer.close()​
await writer.wait_closed()​

if __name__ == "__main__":​
asyncio.run(main())​

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.

You might also like