CodeGym /Cours /Python SELF FR /Module socket

Module socket

Python SELF FR
Niveau 24 , Leçon 1
Disponible

7.1 Qu'est-ce que les sockets ?

Allons encore plus loin. D'abord, on a appris à travailler avec request, ensuite avec http.client, puis avec les proxies. Et après ? Ensuite, nous allons jeter un œil sous le capot de toutes ces bibliothèques...

Un socket (littéralement — prise) est un point dans le réseau, par lequel les données sont envoyées et reçues. On peut considérer le socket comme un point final d'un canal de communication bidirectionnel entre deux programmes, fonctionnant sur une ou différentes machines.

Les sockets supportent divers protocoles réseau, mais deux sont les plus utilisés :

  • TCP (Transmission Control Protocol) : Un protocole fiable qui assure l'établissement de la connexion, la vérification de l'intégrité des données et leur séquencement correct.
  • UDP (User Datagram Protocol) : Un protocole non connecté qui ne garantit pas la livraison des données, mais est plus rapide et efficace pour certains types d'applications.

Pour identifier un socket, on utilise une adresse IP (identifiant l'appareil sur le réseau) et un port (identifiant une application ou un service spécifique sur l'appareil).

Important ! L'adresse IP et le port identifient de manière unique le programme sur le réseau. C'est comme l'adresse d'une maison et le numéro d'appartement. L'adresse de la maison (adresse IP) est l'adresse de votre ordinateur sur le réseau, et le port est le numéro de l'appartement que le programme utilise pour envoyer et recevoir des messages.

Pour en savoir plus sur ce qu'est une adresse IP et un port, vous pouvez consulter les conférences dédiées à l'architecture réseau.

Les principales étapes du travail d'un programme avec les sockets :

  1. Création d'un socket : Le programme crée un socket, en spécifiant le type de protocole (TCP ou UDP).
  2. Liaison à une adresse : Le socket est lié à une adresse IP et un numéro de port pour être accessible pour les connexions ou l'envoi/réception de données.
  3. Écoute et établissement de connexion (pour TCP) :
    • Écoute : Le socket côté serveur est mis en mode écoute, en attente de connexions entrantes.
    • Établissement de connexion : Le client initie la connexion avec le serveur. Le serveur accepte la connexion, créant un nouveau socket pour interagir avec le client.
  4. Échange de données : Les données sont échangées entre le client et le serveur. Dans le cas du TCP, les données sont transmises dans un ordre fiable.
  5. Fermeture de connexion : Après l'échange de données, la connexion est fermée.

Avantages de l'utilisation des sockets :

  • Flexibilité : Les sockets permettent aux applications d'échanger des données indépendamment de leur localisation et de leur plateforme.
  • Performance : Les sockets offrent un moyen rapide et efficace de transmettre des données, notamment avec l'utilisation de l'UDP.
  • Fiabilité (dans le cas du TCP) : Le protocole TCP garantit une livraison fiable des données avec vérification de l'intégrité et récupération des paquets perdus.

7.2 Création d'un socket serveur

Travailler avec les sockets en Python se fait grâce au module intégré socket, qui fournit une interface pour la programmation réseau bas niveau.

Avec les sockets, on peut créer un socket serveur — une application/objet qui recevra des requêtes de clients et leur répondra. Ainsi qu'un socket client — une application/objet qui enverra des requêtes au socket serveur et recevra des réponses de celui-ci.

Pour créer un socket serveur, il faut faire trois choses :

  1. Créer un objet socket serveur.
  2. Le lier (bind) à une adresse IP et un port quelconques.
  3. Activer le mode écoute (listen) des messages entrants.

Ce code ressemblera à peu près à ceci :


import socket

# Création d'un socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
# Liaison du socket à une adresse et un port
server_socket.bind(('localhost', 12345))
    
# Écoute des connexions entrantes
server_socket.listen(5)
print("Le serveur attend des connexions...")

Ici, socket.AF_INET indique que nous utilisons l'IPv4 pour le protocole réseau, et socket.SOCK_STREAM signifie que nous utilisons le TCP. Ces paramètres sont les plus couramment utilisés pour créer des applications réseau.

Une fois qu'un message entrant est reçu, quatre actions supplémentaires doivent être effectuées :

  1. Établir la connexion (accept) avec le client.
  2. Recevoir (receive) la requête (les données) du client.
  3. Envoyer (send) une réponse au client — également certaines données.
  4. Fermer (close) la connexion.

Ce code ressemblera à peu près à ça :


# Acceptation d'une nouvelle connexion
client_socket, client_address = server_socket.accept()
print(f"Connexion établie avec {client_address}")

# Réception des données du client
data = client_socket.recv(1024)
print(f"Reçu : {data.decode('utf-8')}")

# Envoi de données au client
client_socket.sendall(b'Hello, client!')

# Fermeture de la connexion avec le client
client_socket.close()

La méthode sendall() est utilisée à la place de send() car elle garantit que toutes les données seront envoyées. La méthode send() pourrait n'envoyer qu'une partie des données si le buffer se remplit.

Le nombre 1024 dans recv(1024) indique le nombre maximum d'octets qui peut être reçu en une fois. Cela aide à contrôler le volume de données traitées en une opération.

Le code du dernier exemple est généralement exécuté dans une boucle infinie — le serveur traite une requête, puis attend la suivante, la traite, et ainsi de suite en continu.

Si vous souhaitez l'exécuter chez vous ou simplement voir un exemple complet, je le fournis ici :


import socket

# Création d'un socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        
# Liaison du socket à une adresse et un port
server_socket.bind(('localhost', 12345))
        
# Écoute des connexions entrantes
server_socket.listen(5)
print("Le serveur attend des connexions...")
        
while True:
    # Acceptation d'une nouvelle connexion
    client_socket, client_address = server_socket.accept()
    print(f"Connexion établie avec {client_address}")
        
    # Réception des données du client
    data = client_socket.recv(1024)
    print(f"Reçu : {data.decode('utf-8')}")
        
    # Envoi de données au client
    client_socket.sendall(b'Hello, client!')
        
    # Fermeture de la connexion avec le client
    client_socket.close()

7.3 Création d'un socket client

Nous avons créé le socket serveur, maintenant écrivons notre socket client qui contactera le serveur et recevra les données en retour.

Pour cela, il faut effectuer cinq actions :

  1. Créer un objet socket client.
  2. Établir la connexion (connect) avec l'adresse IP et le port de notre socket serveur.
  3. Envoyer (send) un message au serveur.
  4. Recevoir (receive) les données du serveur.
  5. Fermer (close) la connexion.

En réalité, c'est plus simple qu'il n'y paraît. Voici à quoi ressemblera ce code :


import socket

# Création d'un socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
# Établissement de la connexion avec le serveur
client_socket.connect(('localhost', 12345))
    
# Envoi de données au serveur
client_socket.sendall(b'Hello, server!')
    
# Réception des données du serveur
data = client_socket.recv(1024)
print(f"Reçu du serveur : {data.decode('utf-8')}")
    
# Fermeture du socket
client_socket.close()

Si de l'autre côté il n'y a pas de socket serveur en cours d'exécution ou si la connexion est coupée, une exception de type socket.error sera levée. Donc, n'oubliez pas de gérer les exceptions.

Pour aujourd'hui, nous en avons fini avec le travail sur les sockets.

À chaque fois que vous travaillerez avec le réseau, des hôtes, des ports, des adresses IP, des établissements de connexion, des écoutes de requêtes reviendront encore et encore. Ainsi, comprendre comment cela fonctionne au fond vous facilitera grandement la vie et vous aidera à rassembler des connaissances disparates en un tout cohérent.

Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION