Python Chat Server
This guide demonstrates how to build a simple TCP chat room. It consists of a Server that handles connections and broadcasts messages, and a Client that connects to the server to send and receive messages.
Modules Used:
- socket: To establish TCP connections.
threading: To handle multiple clients simultaneously on the server, and to send/receive simultaneously on the client.
The Server Code
The server listens for incoming connections. When a client connects, the server starts a new thread to handle that specific client's messages while continuing to listen for new connections.
Save this as server.py.
import socket
import threading
# Connection Data
HOST = '127.0.0.1' # Localhost
PORT = 55555
# Starting Server
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen()
# Lists For Clients and Their Nicknames
clients = []
nicknames = []
def broadcast(message):
"""Sends a message to all connected clients."""
for client in clients:
client.send(message)
def handle(client):
"""Handles messages from a specific client."""
while True:
try:
# Broadcasting Messages
message = client.recv(1024)
broadcast(message)
except:
# Removing And Closing Clients
index = clients.index(client)
clients.remove(client)
client.close()
nickname = nicknames[index]
broadcast(f'{nickname} left!'.encode('ascii'))
nicknames.remove(nickname)
break
def receive():
"""Accepts new connections."""
while True:
client, address = server.accept()
print(f"Connected with {str(address)}")
# Request And Store Nickname
client.send('NICK'.encode('ascii'))
nickname = client.recv(1024).decode('ascii')
nicknames.append(nickname)
clients.append(client)
print(f"Nickname is {nickname}")
broadcast(f"{nickname} joined!".encode('ascii'))
client.send('Connected to server!'.encode('ascii'))
# Start Handling Thread For Client
thread = threading.Thread(target=handle, args=(client,))
thread.start()
print("Server is listening...")
receive()
The Client Code
The client needs two threads: one to listen for incoming messages from the server (so it doesn't freeze waiting for input) and one to handle user input.
Save this as client.py.
import socket
import threading
nickname = input("Choose your nickname: ")
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 55555))
def receive():
"""Listens for messages from the server."""
while True:
try:
message = client.recv(1024).decode('ascii')
if message == 'NICK':
client.send(nickname.encode('ascii'))
else:
print(message)
except:
print("An error occurred!")
client.close()
break
def write():
"""Sends messages to the server."""
while True:
message = f'{nickname}: {input("")}'
client.send(message.encode('ascii'))
# Starting Threads For Listening And Writing
receive_thread = threading.Thread(target=receive)
receive_thread.start()
write_thread = threading.Thread(target=write)
write_thread.start()
Usage
-
Start the Server: Open a terminal and run:
python server.py -
Start Clients: Open multiple new terminal windows (one for each user) and run:
python client.py -
Chat: Type messages in the client windows. They will appear in all other connected clients.