杰瑞科技汇

python 3 chatserver

Of course! Here is a complete, well-commented, and easy-to-understand Python 3 chat server implementation.

python 3 chatserver-图1
(图片来源网络,侵删)

This solution uses Python's built-in socket and threading libraries, which means you don't need to install any external packages.

Core Concepts

  1. Socket Programming: This is the foundation for all network communication. A socket is like an endpoint for sending or receiving data across a computer network. We'll use socket.socket() to create a communication object.
  2. Threading: A single server can only handle one client at a time using a simple loop. To handle multiple clients simultaneously, we'll use a "thread" for each client. This allows the server to be listening for new connections while also managing conversations with existing clients.
  3. Protocol: We need a simple rule for how messages are formatted. A robust way is to prefix each message with its length. This ensures the client knows exactly how many bytes to read before a message is complete.

The Code: chat_server.py

This single file contains the entire server logic.

import socket
import threading
import sys
# --- Configuration ---
HOST = '127.0.0.1'  # Standard loopback interface address (localhost)
PORT = 65432        # Port to listen on (non-privileged ports are > 1023)
# A dictionary to keep track of connected clients and their nicknames
clients = {}
def handle_client(conn, addr, nickname):
    """
    Handles communication with a single client.
    """
    print(f"[NEW CONNECTION] {nickname} connected from {addr}")
    # Send a welcome message to the new client
    welcome_msg = f"Welcome to the chat, {nickname}! Type 'exit' to leave."
    conn.send(welcome_msg.encode('utf-8'))
    while True:
        try:
            # Receive messages from the client
            message = conn.recv(1024).decode('utf-8')
            if not message:
                # If the client sends an empty message, they have disconnected
                break
            # Check if the client wants to exit
            if message.lower() == 'exit':
                break
            # Broadcast the message to all other clients
            broadcast(f"{nickname}: {message}", conn)
        except ConnectionResetError:
            # This happens if the client closes the connection abruptly
            print(f"[ERROR] Connection with {nickname} was reset.")
            break
    # --- Cleanup when a client disconnects ---
    print(f"[DISCONNECT] {nickname} disconnected.")
    # Remove the client from our dictionary
    if nickname in clients:
        del clients[nickname]
    # Notify all other clients that this user has left
    broadcast(f"SERVER: {nickname} has left the chat.", conn)
    # Close the connection
    conn.close()
def broadcast(message, sender_conn):
    """
    Sends a message to all connected clients except the sender.
    """
    for client_conn, nickname in clients.items():
        if client_conn != sender_conn:
            try:
                client_conn.send(message.encode('utf-8'))
            except:
                # If sending fails, the client is likely disconnected.
                # We'll let the main loop handle the cleanup.
                pass
def start_server():
    """
    Starts the chat server and listens for incoming connections.
    """
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind((HOST, PORT))
    server.listen()
    print(f"[LISTENING] Server is listening on {HOST}:{PORT}")
    try:
        while True:
            # Accept a new connection
            conn, addr = server.accept()
            # Prompt the new client for a nickname
            conn.send("NICK".encode('utf-8'))
            nickname = conn.recv(1024).decode('utf-8')
            # Add the new client to our dictionary
            clients[conn] = nickname
            print(f"[NEW CONNECTION] {addr} connected as '{nickname}'.")
            # Notify all other clients that a new user has joined
            broadcast(f"SERVER: {nickname} has joined the chat.", conn)
            # Start a new thread to handle the client
            thread = threading.Thread(target=handle_client, args=(conn, addr, nickname))
            thread.start()
            print(f"[ACTIVE CONNECTIONS] {threading.active_count() - 1}")
    except KeyboardInterrupt:
        print("\n[SHUTTING DOWN] Server is shutting down.")
    finally:
        # Close all client connections
        for conn in clients:
            conn.close()
        # Close the server socket
        server.close()
        print("[SERVER STOPPED]")
if __name__ == "__main__":
    start_server()

How to Run the Server

  1. Save the code above into a file named chat_server.py.
  2. Open your terminal or command prompt.
  3. Navigate to the directory where you saved the file.
  4. Run the server with the following command:
    python chat_server.py
  5. You will see the following output, indicating the server is running and waiting for connections:
    [LISTENING] Server is listening on 127.0.0.1:65432

The Client-Side Code

To test your server, you need a client. Here is a simple command-line client you can use. Save this as chat_client.py.

import socket
import threading
# --- Server Configuration ---
HOST = '127.0.0.1'  # The server's IP address (localhost)
PORT = 65432        # The port used by the server
def receive_messages(client_socket):
    """Listens for messages from the server and prints them."""
    while True:
        try:
            message = client_socket.recv(1024).decode('utf-8')
            if message == "NICK":
                # Handle nickname prompt
                nickname = input("Enter your nickname: ")
                client_socket.send(nickname.encode('utf-8'))
            else:
                print(message)
        except:
            # This means the server has closed the connection
            print("Connection to the server lost.")
            break
def send_messages(client_socket):
    """Gets input from the user and sends it to the server."""
    while True:
        message = input()
        client_socket.send(message.encode('utf-8'))
        if message.lower() == 'exit':
            break
def start_client():
    """Connects to the server and starts send/receive threads."""
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        client.connect((HOST, PORT))
        print(f"Connected to the server at {HOST}:{PORT}")
    except ConnectionRefusedError:
        print("Could not connect to the server. Is it running?")
        return
    # Start a thread to listen for messages from the server
    receive_thread = threading.Thread(target=receive_messages, args=(client,))
    receive_thread.start()
    # Start a thread to send messages from the user to the server
    send_thread = threading.Thread(target=send_messages, args=(client,))
    send_thread.start()
    # Wait for both threads to complete
    receive_thread.join()
    send_thread.join()
    client.close()
if __name__ == "__main__":
    start_client()

How to Test the Chat Application

  1. Start the Server: In your first terminal, run python chat_server.py. It will say it's listening.
  2. Start Client 1: In a second terminal, run python chat_client.py. It will connect and ask for a nickname (e.g., "Alice"). The server will print that Alice has joined.
  3. Start Client 2: In a third terminal, run python chat_client.py again. It will connect and ask for a nickname (e.g., "Bob"). The server will print that Bob has joined, and Alice's client will see a message that Bob has joined.
  4. Chat!
    • Type a message in Alice's terminal and press Enter. Bob will see it.
    • Type a message in Bob's terminal and press Enter. Alice will see it.
  5. Disconnect:
    • Type exit in either client's terminal. That client will disconnect. The other client will see a message that the user has left.
    • Press Ctrl+C in the server's terminal to shut down the entire server. All connected clients will see an error and disconnect.

This example provides a solid foundation that you can expand upon with features like private messaging, user lists, or a graphical user interface (GUI).

python 3 chatserver-图2
(图片来源网络,侵删)
python 3 chatserver-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇