Comment envoyer et recevoir des messages avec les sockets Python

PythonBeginner
Pratiquer maintenant

Introduction

Les sockets Python constituent un outil puissant pour la communication réseau, vous permettant d'envoyer et de recevoir des messages entre différents systèmes. Dans ce tutoriel, nous vous guiderons à travers le processus d'utilisation des sockets Python pour établir des connexions, transmettre des données et recevoir des réponses. À la fin de ce lab, vous aurez construit à la fois une application client et une application serveur capables de communiquer entre elles sur un réseau.

Ces connaissances pratiques constituent la base du développement d'applications réseau plus complexes, des programmes de chat aux systèmes distribués.

Ceci est un Guided Lab, qui fournit des instructions étape par étape pour vous aider à apprendre et à pratiquer. Suivez attentivement les instructions pour compléter chaque étape et acquérir une expérience pratique. Les données historiques montrent que c'est un laboratoire de niveau intermédiaire avec un taux de réussite de 71%. Il a reçu un taux d'avis positifs de 100% de la part des apprenants.

Comprendre les bases des sockets et créer votre premier socket

Commençons par comprendre ce que sont les sockets et comment ils fonctionnent en Python. Nous allons ensuite créer notre premier socket pour voir comment il est initialisé.

Que sont les sockets Python ?

Les sockets sont des points d'extrémité pour l'envoi et la réception de données sur un réseau. Ils fournissent une interface de programmation pour la communication réseau, permettant aux applications d'échanger des informations quel que soit leur emplacement.

En programmation réseau, nous utilisons généralement un modèle client-serveur :

  • Le serveur attend les connexions entrantes et traite les requêtes
  • Le client initie la communication en se connectant au serveur

Le module socket intégré de Python facilite l'utilisation des sockets sans avoir à comprendre tous les détails complexes des protocoles réseau.

Types de sockets

Les deux types de sockets les plus courants sont :

  • TCP (Transmission Control Protocol) : Fournit une livraison de données fiable et ordonnée
  • UDP (User Datagram Protocol) : Fournit une transmission de données plus rapide mais non fiable

Pour ce lab, nous nous concentrerons sur les sockets TCP, qui sont le type le plus couramment utilisé pour les applications nécessitant une communication fiable.

Créer votre premier socket

Créons un script Python simple pour initialiser un socket. Ouvrez le WebIDE et suivez ces étapes :

  1. Tout d'abord, créons un répertoire pour notre projet de programmation de sockets :
mkdir -p ~/project/socket_lab
cd ~/project/socket_lab
  1. Maintenant, créez un nouveau fichier Python appelé socket_basics.py :

Dans le WebIDE, cliquez sur le bouton "New File" ou utilisez le menu "File" et sélectionnez "New File", puis nommez-le socket_basics.py dans le répertoire socket_lab.

  1. Ajoutez le code suivant pour démontrer comment créer un socket :
import socket

## Creating a socket
print("Creating a new socket...")
my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print(f"Socket created: {my_socket}")

## Explaining the parameters:
print("\nSocket parameters explained:")
print("AF_INET: Using IPv4 addressing")
print("SOCK_STREAM: Using TCP protocol for reliable data transmission")

## Getting available socket methods
print("\nSome methods available on socket objects:")
methods = [method for method in dir(my_socket) if not method.startswith('_')]
print(', '.join(methods[:10]) + '...')  ## Showing first 10 methods

## Closing the socket
my_socket.close()
print("\nSocket closed")
  1. Enregistrez le fichier.

  2. Exécutez le script pour voir la sortie :

python3 ~/project/socket_lab/socket_basics.py

Vous devriez voir une sortie similaire à celle-ci :

Creating a new socket...
Socket created: <socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)>

Socket parameters explained:
AF_INET: Using IPv4 addressing
SOCK_STREAM: Using TCP protocol for reliable data transmission

Some methods available on socket objects:
accept, bind, close, connect, connect_ex, detach, fileno, getpeername, getsockname, getsockopt...

Socket closed

Cette sortie montre que nous avons créé avec succès un objet socket et exploré certaines de ses propriétés. Dans les sections suivantes, nous utiliserons des sockets pour construire une application serveur et client qui peuvent communiquer entre elles.

Fonctions clés des sockets

Avant de continuer, comprenons quelques fonctions clés des sockets que nous allons utiliser :

  • socket() - Crée un nouvel objet socket
  • bind() - Associe le socket à une interface réseau et un port spécifiques
  • listen() - Permet au serveur d'accepter les connexions
  • accept() - Accepte une connexion d'un client
  • connect() - Se connecte à une adresse distante
  • send() - Envoie des données à un socket connecté
  • recv() - Reçoit des données d'un socket connecté
  • close() - Ferme le socket

Dans l'étape suivante, nous allons créer un serveur en utilisant ces fonctions.

Création d'un serveur de socket simple

Maintenant que nous comprenons les bases des sockets, créons un serveur simple qui écoute les connexions et reçoit des messages des clients.

Comment fonctionne un serveur de socket

Un serveur de socket suit ces étapes générales :

  1. Créer un socket
  2. Le lier à une adresse et un port
  3. Écouter les connexions entrantes
  4. Accepter les connexions client
  5. Recevoir et traiter les données
  6. Envoyer une réponse si nécessaire
  7. Fermer la connexion

Implémentons ce modèle en Python.

Création du serveur

  1. Créez un nouveau fichier Python appelé server.py dans le répertoire socket_lab :

Dans le WebIDE, cliquez sur le bouton "New File" ou utilisez le menu "File" et sélectionnez "New File", puis nommez-le server.py dans le répertoire socket_lab.

  1. Ajoutez le code suivant pour créer un serveur de base :
import socket

def start_server():
    ## Server configuration
    host = '127.0.0.1'  ## localhost
    port = 12345        ## arbitrary non-privileged port

    ## Create socket
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    ## Set socket option to reuse address (helps avoid "Address already in use" errors)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    ## Bind socket to address and port
    server_socket.bind((host, port))

    ## Listen for connections (queue up to 5 connection requests)
    server_socket.listen(5)

    print(f"Server started on {host}:{port}")
    print("Waiting for client connection...")

    try:
        ## Accept connection
        client_socket, client_address = server_socket.accept()
        print(f"Connection established with {client_address}")

        ## Receive data from client
        data = client_socket.recv(1024)  ## receive up to 1024 bytes
        print(f"Message received: {data.decode()}")

        ## Send response to client
        response = "Message received by server"
        client_socket.send(response.encode())

        ## Close client connection
        client_socket.close()

    except KeyboardInterrupt:
        print("\nServer shutting down...")
    finally:
        ## Close server socket
        server_socket.close()
        print("Server socket closed")

if __name__ == "__main__":
    start_server()
  1. Enregistrez le fichier.

Comprendre le code du serveur

Décomposons les principaux composants de notre serveur :

  • Création du socket : Nous créons un socket TCP en utilisant socket.socket() avec AF_INET (IPv4) et SOCK_STREAM (protocole TCP).

  • Options du socket : Nous définissons une option pour réutiliser l'adresse, ce qui permet d'éviter les erreurs "Address already in use" lors du redémarrage rapide du serveur après l'arrêt.

  • Liaison (Binding) : Nous lions le socket à l'adresse 127.0.0.1 (localhost) et au port 12345. Cela indique au système d'exploitation que nous souhaitons recevoir des connexions à cet emplacement réseau spécifique.

  • Écoute (Listening) : L'appel listen(5) indique au socket de mettre en file d'attente jusqu'à 5 demandes de connexion avant de refuser de nouvelles connexions.

  • Acceptation des connexions : La méthode accept() bloque (attend) jusqu'à ce qu'un client se connecte, puis renvoie un nouvel objet socket pour communiquer avec ce client, ainsi que l'adresse du client.

  • Réception des données : Nous utilisons recv(1024) pour recevoir jusqu'à 1024 octets de données du client. Les données sont reçues sous forme d'octets, nous utilisons donc decode() pour les convertir en chaîne de caractères.

  • Envoi de données : Nous renvoyons une réponse au client en utilisant la méthode send(). Nous encode() la chaîne de caractères pour la convertir en octets avant de l'envoyer.

  • Fermeture : Enfin, nous fermons à la fois le socket client et le socket serveur pour libérer les ressources.

Tester le serveur

Exécutons notre serveur pour le voir en action. Il ne fera pas grand-chose pour le moment puisque nous n'avons pas créé de client, mais nous pouvons vérifier qu'il démarre correctement :

python3 ~/project/socket_lab/server.py

Vous devriez voir une sortie comme celle-ci :

Server started on 127.0.0.1:12345
Waiting for client connection...

Le serveur attend maintenant qu'un client se connecte. Puisque nous n'avons pas encore de client, appuyez sur Ctrl+C pour arrêter le serveur :

^C
Server shutting down...
Server socket closed

Dans l'étape suivante, nous allons créer un client pour nous connecter à notre serveur.

Construire un client pour se connecter au serveur

Maintenant que nous avons notre serveur, nous devons créer un client qui peut s'y connecter et envoyer des messages. Construisons une application client simple.

Comment fonctionne un client de socket

Un client de socket suit ces étapes générales :

  1. Créer un socket
  2. Se connecter à l'adresse et au port d'un serveur
  3. Envoyer des données
  4. Recevoir une réponse
  5. Fermer la connexion

Création du client

  1. Créez un nouveau fichier Python appelé client.py dans le répertoire socket_lab :

Dans le WebIDE, cliquez sur le bouton "New File" ou utilisez le menu "File" et sélectionnez "New File", puis nommez-le client.py dans le répertoire socket_lab.

  1. Ajoutez le code suivant pour créer un client de base :
import socket

def start_client():
    ## Server information to connect to
    host = '127.0.0.1'  ## localhost - same as server
    port = 12345        ## same port as server

    try:
        ## Create socket
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        ## Connect to server
        print(f"Connecting to server at {host}:{port}...")
        client_socket.connect((host, port))
        print("Connected to server")

        ## Send a message
        message = "Hello from the client!"
        print(f"Sending message: {message}")
        client_socket.send(message.encode())

        ## Receive response
        response = client_socket.recv(1024)
        print(f"Response from server: {response.decode()}")

    except ConnectionRefusedError:
        print("Connection failed. Make sure the server is running.")
    except Exception as e:
        print(f"An error occurred: {e}")
    finally:
        ## Close socket
        client_socket.close()
        print("Connection closed")

if __name__ == "__main__":
    start_client()
  1. Enregistrez le fichier.

Comprendre le code du client

Examinons les parties clés de notre code client :

  • Création du socket : Similaire au serveur, nous créons un socket TCP en utilisant socket.socket().

  • Connexion : Au lieu de lier et d'écouter, le client utilise connect() pour établir une connexion avec le serveur à l'hôte et au port spécifiés.

  • Envoi de données : Nous envoyons un message en utilisant la méthode send(), en veillant à encoder la chaîne de caractères en octets.

  • Réception de données : Nous utilisons recv(1024) pour recevoir la réponse du serveur et la décoder en chaîne de caractères.

  • Gestion des erreurs : Nous incluons la gestion des erreurs pour intercepter les problèmes courants tels que le serveur indisponible (ConnectionRefusedError).

  • Fermeture : Nous fermons le socket lorsque nous avons terminé pour libérer des ressources.

Tester le client et le serveur ensemble

Testons maintenant notre client et notre serveur ensemble. Nous devrons les exécuter dans des fenêtres de terminal séparées.

  1. Tout d'abord, démarrez le serveur :
python3 ~/project/socket_lab/server.py

Vous devriez voir :

Server started on 127.0.0.1:12345
Waiting for client connection...
  1. Ouvrez un nouveau terminal dans WebIDE (en cliquant sur le bouton "+" dans le panneau du terminal) et exécutez le client :
python3 ~/project/socket_lab/client.py

Vous devriez voir une sortie comme celle-ci dans le terminal client :

Connecting to server at 127.0.0.1:12345...
Connected to server
Sending message: Hello from the client!
Response from server: Message received by server
Connection closed

Et dans le terminal du serveur, vous devriez voir :

Connection established with ('127.0.0.1', 55234)  ## The port number may differ
Message received: Hello from the client!

Après que le client se déconnecte, le serveur s'arrêtera car notre implémentation actuelle ne gère qu'une seule connexion. Appuyez sur Ctrl+C dans le terminal du serveur pour l'arrêter s'il est toujours en cours d'exécution.

Cela démontre une communication réussie entre un client et un serveur utilisant des sockets Python. Le client est capable d'envoyer un message au serveur, et le serveur peut le recevoir et renvoyer une réponse.

Construire un serveur continu et un client interactif

Notre implémentation actuelle serveur-client ne gère qu'un seul échange de messages avant de se fermer. La plupart des applications du monde réel doivent maintenir les connexions et gérer plusieurs messages. Améliorons notre code pour créer une expérience plus interactive.

Améliorer le serveur

Tout d'abord, modifions notre serveur pour qu'il accepte en continu les connexions et gère plusieurs messages de chaque client.

  1. Ouvrez le fichier server.py dans le WebIDE et remplacez le code par :
import socket

def start_server():
    ## Server configuration
    host = '127.0.0.1'
    port = 12345

    ## Create socket
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    try:
        ## Bind and listen
        server_socket.bind((host, port))
        server_socket.listen(5)

        print(f"Server running on {host}:{port}")
        print("Press Ctrl+C to stop the server")

        while True:  ## Continuous server loop
            print("\nWaiting for a connection...")
            client_socket, client_address = server_socket.accept()
            print(f"Connected to client: {client_address}")

            ## Handle client communication
            handle_client(client_socket)

    except KeyboardInterrupt:
        print("\nServer is shutting down...")
    finally:
        server_socket.close()
        print("Server closed")

def handle_client(client_socket):
    try:
        while True:  ## Keep receiving messages until client disconnects
            ## Receive data
            data = client_socket.recv(1024)

            ## If no data, client has disconnected
            if not data:
                break

            received_message = data.decode()
            print(f"Received: {received_message}")

            ## Process the message (in this case, just echo it back with a prefix)
            response = f"Server received: {received_message}"
            client_socket.send(response.encode())

    except Exception as e:
        print(f"Error handling client: {e}")
    finally:
        ## Close client socket
        client_socket.close()
        print("Client connection closed")

if __name__ == "__main__":
    start_server()
  1. Enregistrez le fichier.

Améliorer le client

Maintenant, créons un client interactif qui permet aux utilisateurs d'envoyer plusieurs messages.

  1. Ouvrez le fichier client.py dans le WebIDE et remplacez le code par :
import socket

def start_client():
    ## Server information
    host = '127.0.0.1'
    port = 12345

    try:
        ## Create socket and connect
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        print(f"Connecting to server at {host}:{port}...")
        client_socket.connect((host, port))
        print("Connected to server!")

        ## Interactive message sending
        while True:
            ## Get message from user
            message = input("\nEnter message to send (or 'quit' to exit): ")

            ## Check if user wants to quit
            if message.lower() == 'quit':
                print("Closing connection...")
                break

            ## Send message
            client_socket.send(message.encode())

            ## Receive response
            response = client_socket.recv(1024)
            print(f"Response from server: {response.decode()}")

    except ConnectionRefusedError:
        print("Connection failed. Make sure the server is running.")
    except Exception as e:
        print(f"An error occurred: {e}")
    finally:
        ## Close connection
        try:
            client_socket.close()
        except:
            pass
        print("Disconnected from server")

if __name__ == "__main__":
    start_client()
  1. Enregistrez le fichier.

Comprendre le code amélioré

Améliorations du serveur :

  • Nous avons ajouté une boucle while True extérieure pour accepter en continu de nouvelles connexions client.
  • Nous avons créé une fonction handle_client distincte pour gérer la communication avec chaque client.
  • La fonction de gestion du client a sa propre boucle pour recevoir plusieurs messages du même client.
  • Nous vérifions les données vides (if not data:), ce qui indique que le client s'est déconnecté.

Améliorations du client :

  • Nous avons ajouté une boucle while True pour permettre l'envoi de plusieurs messages.
  • Nous demandons à l'utilisateur de saisir une entrée et de l'envoyer au serveur.
  • L'utilisateur peut taper 'quit' pour quitter la boucle et fermer la connexion.
  • Après avoir envoyé chaque message, nous attendons et affichons la réponse du serveur.

Tester les applications améliorées

Testons nos serveurs et clients améliorés :

  1. Démarrez le serveur amélioré dans un terminal :
python3 ~/project/socket_lab/server.py

Vous devriez voir :

Server running on 127.0.0.1:12345
Press Ctrl+C to stop the server

Waiting for a connection...
  1. Dans un nouveau terminal, exécutez le client amélioré :
python3 ~/project/socket_lab/client.py

Vous devriez voir :

Connecting to server at 127.0.0.1:12345...
Connected to server!

Enter message to send (or 'quit' to exit):
  1. Tapez un message et appuyez sur Entrée :
Enter message to send (or 'quit' to exit): Hello, server!
Response from server: Server received: Hello, server!

Enter message to send (or 'quit' to exit):
  1. Essayez d'envoyer quelques autres messages. Dans le terminal du serveur, vous devriez voir chaque message reçu :
Connected to client: ('127.0.0.1', 59042)
Received: Hello, server!
Received: This is another message
  1. Lorsque vous avez terminé, tapez 'quit' dans le client :
Enter message to send (or 'quit' to exit): quit
Closing connection...
Disconnected from server
  1. Dans le terminal du serveur, vous devriez voir :
Client connection closed

Waiting for a connection...
  1. Le serveur continue de fonctionner et est prêt à accepter de nouvelles connexions. Vous pouvez démarrer un autre client ou appuyer sur Ctrl+C pour arrêter le serveur.

Grâce à ces améliorations, nous avons créé un système de communication client-serveur plus réaliste et interactif en utilisant des sockets Python.

Clients multiples et gestion des erreurs

Dans les applications du monde réel, un serveur doit généralement gérer plusieurs clients simultanément et gérer avec élégance diverses conditions d'erreur. Améliorons notre implémentation en tenant compte de ces considérations.

Comprendre la gestion concurrente des clients

Il existe plusieurs façons de gérer plusieurs clients simultanément :

  1. Threading (Threads) : Créez un nouveau thread pour chaque connexion client
  2. Process-based (Basé sur les processus) : Générez un nouveau processus pour chaque client
  3. Asynchronous I/O (E/S asynchrones) : Utilisez des E/S non bloquantes avec une boucle d'événements

Pour ce lab, nous allons implémenter une approche basée sur le threading, qui est relativement simple à comprendre et à mettre en œuvre.

Améliorer le serveur pour plusieurs clients

Modifions notre serveur pour gérer plusieurs clients à l'aide de threads :

  1. Ouvrez le fichier server.py dans le WebIDE et remplacez le code par :
import socket
import threading

def handle_client(client_socket, client_address):
    """Handle communication with a single client"""
    try:
        print(f"[NEW CONNECTION] {client_address} connected.")

        while True:
            ## Receive client data
            try:
                data = client_socket.recv(1024)
                if not data:
                    break  ## Client disconnected

                message = data.decode()
                print(f"[{client_address}] {message}")

                ## Send response
                response = f"Message '{message}' received successfully"
                client_socket.send(response.encode())

            except ConnectionResetError:
                print(f"[{client_address}] Connection reset by client")
                break

    except Exception as e:
        print(f"[ERROR] {e}")

    finally:
        ## Clean up when client disconnects
        client_socket.close()
        print(f"[DISCONNECTED] {client_address} disconnected")

def start_server():
    """Start the server and listen for connections"""
    ## Server configuration
    host = '127.0.0.1'
    port = 12345

    ## Create socket
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    ## Set socket option to reuse address
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    try:
        ## Bind to host and port
        server_socket.bind((host, port))

        ## Listen for connections
        server_socket.listen(5)
        print(f"[STARTING] Server is listening on {host}:{port}")

        while True:
            ## Accept client connection
            client_socket, client_address = server_socket.accept()

            ## Create a new thread to handle the client
            client_thread = threading.Thread(
                target=handle_client,
                args=(client_socket, client_address)
            )
            client_thread.daemon = True  ## Thread will close when main program exits
            client_thread.start()

            ## Display active connections
            print(f"[ACTIVE CONNECTIONS] {threading.active_count() - 1}")

    except KeyboardInterrupt:
        print("\n[SHUTTING DOWN] Server is shutting down...")
    except Exception as e:
        print(f"[ERROR] {e}")
    finally:
        server_socket.close()
        print("[CLOSED] Server socket closed")

if __name__ == "__main__":
    start_server()
  1. Enregistrez le fichier.

Améliorer le client avec la gestion des erreurs

Améliorons également notre client avec une meilleure gestion des erreurs :

  1. Ouvrez le fichier client.py dans le WebIDE et remplacez le code par :
import socket
import sys
import time

def start_client():
    """Start a client that connects to the server"""
    ## Server information
    host = '127.0.0.1'
    port = 12345

    ## Create socket
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    ## Set a timeout for connection attempts (5 seconds)
    client_socket.settimeout(5)

    try:
        ## Connect to server
        print(f"[CONNECTING] Connecting to server at {host}:{port}...")
        client_socket.connect((host, port))

        ## Reset timeout to none for regular communication
        client_socket.settimeout(None)

        print("[CONNECTED] Connected to server")

        ## Communication loop
        while True:
            ## Get user input
            message = input("\nEnter message (or 'quit' to exit): ")

            if message.lower() == 'quit':
                print("[CLOSING] Closing connection by request...")
                break

            try:
                ## Send message
                client_socket.send(message.encode())

                ## Wait for response
                response = client_socket.recv(1024)
                print(f"[RESPONSE] {response.decode()}")

            except ConnectionResetError:
                print("[ERROR] Connection was reset by the server")
                break
            except ConnectionAbortedError:
                print("[ERROR] Connection was aborted")
                break
            except Exception as e:
                print(f"[ERROR] {e}")
                break

    except socket.timeout:
        print("[TIMEOUT] Connection attempt timed out. Is the server running?")
    except ConnectionRefusedError:
        print("[REFUSED] Connection refused. Make sure the server is running.")
    except KeyboardInterrupt:
        print("\n[INTERRUPT] Client shutting down...")
    except Exception as e:
        print(f"[ERROR] {e}")

    finally:
        ## Close socket
        try:
            client_socket.close()
            print("[DISCONNECTED] Disconnected from server")
        except:
            pass

if __name__ == "__main__":
    start_client()
  1. Enregistrez le fichier.

Comprendre le code amélioré

Améliorations du serveur :

  • Nous avons ajouté le module threading pour gérer plusieurs clients simultanément.
  • Chaque connexion client est désormais gérée dans un thread séparé.
  • Nous avons amélioré la gestion des erreurs avec des captures d'exceptions plus spécifiques.
  • Nous affichons le nombre de connexions client actives.
  • Les threads sont définis comme "daemon", ce qui signifie qu'ils se fermeront automatiquement lorsque le programme principal se terminera.

Améliorations du client :

  • Nous avons ajouté un délai d'attente de connexion pour éviter le blocage si le serveur n'est pas disponible.
  • Nous avons amélioré la gestion des erreurs avec des captures d'exceptions spécifiques pour différentes erreurs réseau.
  • Nous avons ajouté des messages d'état plus descriptifs avec une mise en forme claire.

Tester le serveur multi-clients

Testons nos applications améliorées :

  1. Démarrez le serveur :
python3 ~/project/socket_lab/server.py

Vous devriez voir :

[STARTING] Server is listening on 127.0.0.1:12345
  1. Dans un nouveau terminal, démarrez un client :
python3 ~/project/socket_lab/client.py
  1. Démarrez un autre client dans un troisième terminal :
python3 ~/project/socket_lab/client.py
  1. Dans le terminal du serveur, vous devriez voir les deux connexions :
[NEW CONNECTION] ('127.0.0.1', 59124) connected.
[ACTIVE CONNECTIONS] 1
[NEW CONNECTION] ('127.0.0.1', 59126) connected.
[ACTIVE CONNECTIONS] 2
  1. Envoyez des messages des deux clients et observez le serveur les recevoir :
[('127.0.0.1', 59124)] Hello from client 1
[('127.0.0.1', 59126)] Hello from client 2
  1. Lorsque vous avez terminé, tapez 'quit' dans chaque client pour vous déconnecter, ou appuyez sur Ctrl+C dans le terminal du serveur pour arrêter le serveur.

Gérer le serveur non en cours d'exécution

Testons également ce qui se passe lorsque le serveur n'est pas en cours d'exécution :

  1. Assurez-vous que le serveur est arrêté (appuyez sur Ctrl+C s'il est en cours d'exécution)

  2. Essayez d'exécuter un client :

python3 ~/project/socket_lab/client.py

Vous devriez voir :

[CONNECTING] Connecting to server at 127.0.0.1:12345...
[REFUSED] Connection refused. Make sure the server is running.
[DISCONNECTED] Disconnected from server

Le client gère désormais l'erreur avec élégance, informant l'utilisateur que le serveur pourrait ne pas être en cours d'exécution.

Grâce à ces améliorations, nous avons créé un système client-serveur robuste capable de gérer plusieurs clients et diverses conditions d'erreur. Il s'agit d'une base solide pour le développement d'applications réseau plus complexes.

Résumé

Félicitations pour avoir terminé ce lab sur la programmation de sockets Python. Vous avez réussi à apprendre comment :

  1. Créer des objets socket pour la communication réseau
  2. Implémenter un serveur TCP qui écoute les connexions
  3. Construire une application cliente qui se connecte à un serveur
  4. Envoyer et recevoir des messages entre le client et le serveur
  5. Améliorer votre serveur pour gérer plusieurs clients simultanément
  6. Mettre en œuvre une gestion robuste des erreurs, tant côté client que côté serveur

Ces compétences constituent les bases de la programmation réseau et peuvent être appliquées pour construire un large éventail d'applications en réseau, des simples programmes de chat aux systèmes distribués complexes.

Pour poursuivre votre parcours d'apprentissage, envisagez d'explorer :

  • L'implémentation de connexions socket sécurisées avec SSL/TLS
  • La construction d'un protocole plus complexe pour l'échange de données structurées
  • La création d'une interface graphique (GUI) pour votre application cliente
  • L'utilisation d'E/S asynchrones pour des performances supérieures avec de nombreuses connexions simultanées

Les capacités de programmation de sockets de Python en font un excellent choix pour le développement d'applications réseau, offrant un équilibre entre simplicité et puissance que peu d'autres langages peuvent égaler.