Prerequisites:
Before starting, ensure you have Python installed on your system. This example assumes Python 3.x.
Server Implementation:
First, let's create the server-side implementation.
Server.py:
import socket
import threading
# Server configuration
HOST = 'localhost'
PORT = 12345
# List to store client connections
clients = []
def handle_client(client_socket, client_address):
print(f"Accepted connection from {client_address}")
while True:
try:
# Receive message from client
message = client_socket.recv(1024).decode('utf-8')
if not message:
# If no message received, close the connection
clients.remove(client_socket)
client_socket.close()
print(f"Connection closed by {client_address}")
break
# Broadcast message to all clients
print(f"Received from {client_address}: {message}")
broadcast(message, client_socket)
except Exception as e:
print(f"Exception occurred: {e}")
break
def broadcast(message, sender_socket):
for client in clients:
# Send message to all clients except the sender
if client != sender_socket:
try:
client.send(message.encode('utf-8'))
except Exception as e:
print(f"Error broadcasting message: {e}")
def start_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(5)
print(f"Server is listening on {HOST}:{PORT}")
while True:
try:
# Accept client connection
client_socket, client_address = server_socket.accept()
clients.append(client_socket)
# Handle client in a separate thread
client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address))
client_thread.start()
except KeyboardInterrupt:
print("\nServer shutting down...")
break
except Exception as e:
print(f"Exception occurred: {e}")
break
server_socket.close()
if __name__ == "__main__":
start_server()
Client Implementation:
Next, let's create the client-side implementation.
Client.py:
import socket
import threading
# Server configuration
HOST = 'localhost'
PORT = 12345
def receive_messages(client_socket):
while True:
try:
# Receive message from server
message = client_socket.recv(1024).decode('utf-8')
if message:
print(f"\n{message}")
except Exception as e:
print(f"Error receiving message: {e}")
break
def send_messages(client_socket):
while True:
try:
# Send message to server
message = input("")
client_socket.send(message.encode('utf-8'))
except KeyboardInterrupt:
print("\nExiting...")
break
except Exception as e:
print(f"Error sending message: {e}")
break
def start_client():
try:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((HOST, PORT))
# Start threads for sending and receiving messages
receive_thread = threading.Thread(target=receive_messages, args=(client_socket,))
send_thread = threading.Thread(target=send_messages, args=(client_socket,))
receive_thread.start()
send_thread.start()
receive_thread.join()
send_thread.join()
except Exception as e:
print(f"Error connecting to server: {e}")
finally:
client_socket.close()
if __name__ == "__main__":
start_client()
Explanation:
Server (
server.py
):- The server listens on
localhost
(127.0.0.1
) and port12345
. - It accepts incoming client connections using
socket.accept()
. - Each client connection is handled in a separate thread (
handle_client
function). - Messages received from one client are broadcasted to all connected clients (
broadcast
function). - The server shuts down gracefully on
KeyboardInterrupt
(Ctrl+C).
- The server listens on
Client (
client.py
):- The client connects to the server running on
localhost
(127.0.0.1
) and port12345
. - It has two threads:
- One for receiving messages (
receive_messages
function). - One for sending messages (
send_messages
function).
- One for receiving messages (
- Messages typed by the user are sent to the server.
- Messages received from the server are displayed on the command line.
- The client connects to the server running on
Running the Chat Application:
Open a terminal and start the server:
bashpython server.py
Open multiple terminals (or use multiple instances) to simulate multiple clients:
bashpython client.py
Type messages in the client terminals to send them to the server and see them broadcasted to all connected clients.
Notes:
- This example provides a basic foundation for a CLI-based chat tool using socket programming in Python.
- For real-world applications, consider adding more error handling, authentication, encryption, and other features to enhance security and functionality.
- Ensure that the server and client are running on the same network or reachable network for proper communication (
localhost
in this example). - Socket programming requires careful handling of network connections and exceptions to ensure robustness and stability.
This project serves as a great starting point for learning about network programming, client-server architecture, and building command-line applications in Python. Adjust and expand upon it based on your specific requirements and interests!
0 Comments