Réseautage en Python
Programmation Réseau en Python
Section titled “Programmation Réseau en Python”Python offre un support complet pour la programmation réseau, allant de l’accès aux sockets de bas niveau aux bibliothèques de haut niveau pour les protocoles d’application courants.
- Accès de Bas Niveau : Le module
socketfournit un accès à l’interface de socket BSD, permettant l’implémentation directe de clients et de serveurs utilisant les protocoles TCP (orienté connexion) et UDP (sans connexion). - Accès de Haut Niveau : Les bibliothèques standard offrent des abstractions pour des protocoles comme HTTP (
http.client,urllib.request), FTP (ftplib), SMTP (smtplib), POP3 (poplib), IMAP (imaplib), etc. Des bibliothèques tierces commerequestssimplifient davantage les interactions HTTP.
Ce chapitre se concentre sur les fondamentaux de la programmation de sockets de bas niveau à l’aide du module socket.
Que sont les Sockets ?
Section titled “Que sont les Sockets ?”Les sockets sont les points d’extrémité d’un lien de communication bidirectionnel entre deux programmes exécutés sur un réseau. Un socket est lié à un numéro de port afin que la couche TCP puisse identifier l’application à laquelle les données sont destinées.
Les sockets facilitent la communication au sein d’un même processus, entre processus sur la même machine (en utilisant des sockets de domaine Unix ou de bouclage), ou entre processus sur différentes machines via Internet.
Terminologie Clé des Sockets :
| Terme | Description |
|---|---|
| Domaine (ou Famille) | Spécifie la famille de protocoles. Valeurs courantes :AF_INET : Protocoles IPv4.AF_INET6 : Protocoles IPv6.AF_UNIX : Sockets de domaine Unix (pour la communication inter-processus locale). |
| Type | Spécifie la sémantique de communication. Valeurs courantes :SOCK_STREAM : Flux orienté connexion, fiable (TCP).SOCK_DGRAM : Datagrammes sans connexion, non fiables (UDP). |
| Protocole | Généralement 0, permettant au système de choisir le protocole approprié en fonction du domaine et du type (par exemple, IPPROTO_TCP pour SOCK_STREAM, IPPROTO_UDP pour SOCK_DGRAM). |
| Nom d’hôte | Identifie une interface réseau. Peut être un nom de domaine (par exemple, ‘www.example.com’), une chaîne d’adresse IPv4 (par exemple, ‘192.168.1.1’), une chaîne d’adresse IPv6, une chaîne vide ('') représentant INADDR_ANY (écoute sur toutes les interfaces disponibles), ou 'localhost' / '127.0.0.1' pour l’interface de bouclage. |
| Port | Un nombre (0-65535) identifiant un processus ou un service spécifique sur un hôte. Les ports 0-1023 sont des ports bien connus nécessitant généralement des privilèges root/administrateur. |
Le Module socket
Section titled “Le Module socket”Le cœur de la programmation de sockets en Python est le module socket.
Création d’un Socket :
Section titled “Création d’un Socket :”Utilisez socket.socket() pour créer un nouvel objet socket.
s = socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0)Paramètres courants :
family: Domaine du socket (par exemple,socket.AF_INETpour IPv4).type: Type de socket (par exemple,socket.SOCK_STREAMpour TCP,socket.SOCK_DGRAMpour UDP).proto: Numéro de protocole (généralement 0).
Utilisation de l’instruction with (Recommandé) :
Section titled “Utilisation de l’instruction with (Recommandé) :”Les sockets doivent être fermés lorsqu’ils ne sont plus nécessaires. L’instruction with garantit que les sockets sont fermés automatiquement, de manière similaire à la gestion des fichiers.
import socket
try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: # Utiliser le socket 's' ici print("Socket créé avec succès.") # Le socket 's' sera fermé automatiquement à la sortie du bloc 'with'except socket.error as err: print(f"La création du socket a échoué avec l'erreur : {err}")Méthodes Essentielles des Sockets :
Section titled “Méthodes Essentielles des Sockets :”Méthodes des Sockets Serveur (TCP) :
Section titled “Méthodes des Sockets Serveur (TCP) :”| Méthode | Description |
|---|---|
s.bind((host, port)) | Lie le socket à une interface réseau spécifique (host) et un numéro de port. |
s.listen(backlog) | Permet au serveur d’accepter des connexions. backlog spécifie le nombre maximal de connexions en file d’attente. |
s.accept() | Attend une connexion client entrante. Renvoie un tuple (conn, addr) où conn est un nouvel objet socket pour la communication avec le client, et addr est le tuple d’adresse du client. |
Méthodes des Sockets Client (TCP) :
Section titled “Méthodes des Sockets Client (TCP) :”| Méthode | Description |
|---|---|
s.connect((host, port)) | Connecte le socket client à un serveur à l’host et au port spécifiés. |
Méthodes Générales des Sockets (TCP & UDP) :
Section titled “Méthodes Générales des Sockets (TCP & UDP) :”| Méthode | Description |
|---|---|
s.send(bytes) | Transmet des données TCP. Les données doivent être de type bytes. Renvoie le nombre d’octets envoyés. |
s.recv(bufsize) | Reçoit des données TCP. bufsize est la quantité maximale de données (en octets) à recevoir en une seule fois. Renvoie les données reçues sous forme de bytes. |
s.sendall(bytes) | Transmet toutes les données de type bytes pour TCP. Gère les envois partiels potentiels. |
s.sendto(bytes, address) | Transmet un datagramme UDP (bytes) à l’adresse spécifiée sous forme de tuple (host, port). |
s.recvfrom(bufsize) | Reçoit un datagramme UDP. Renvoie un tuple (bytes, address) où bytes sont les données et address est l’adresse de l’expéditeur. |
s.close() | Ferme le socket. Géré automatiquement par l’instruction with. |
socket.gethostname() | Renvoie le nom d’hôte standard de la machine locale. |
Important : En Python 3, les méthodes de socket send(), recv(), sendto() et recvfrom() opèrent sur des objets bytes, et non sur des chaînes de caractères. Vous devez encoder les chaînes en octets avant l’envoi et décoder les octets en chaînes après la réception.
Un Simple Serveur Écho TCP
Section titled “Un Simple Serveur Écho TCP”Ce serveur écoute sur un port spécifique, accepte les connexions client, lit les données du client et renvoie les mêmes données (les renvoie en écho).
#!/usr/bin/env python3import socket
HOST = '127.0.0.1' # Adresse d'interface de bouclage standard (localhost)PORT = 65432 # Port d'écoute (les ports non privilégiés sont > 1023)
def run_server(): # Utiliser l'instruction 'with' pour la fermeture automatique du socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: try: s.bind((HOST, PORT)) s.listen() print(f"Serveur écoutant sur {HOST}:{PORT}")
# Attendre une connexion conn, addr = s.accept() # Appel bloquant
# Utiliser 'with' aussi pour le socket de connexion client with conn: print(f"Connecté par {addr}") while True: # Recevoir des données (jusqu'à 1024 octets) data = conn.recv(1024) if not data: # Si recv renvoie des octets vides, le client a fermé la connexion print(f"Client {addr} déconnecté.") break
# Décoder les octets reçus en chaîne de caractères pour l'affichage print(f"Reçu de {addr} : {data.decode('utf-8')}")
# Renvoyer les données au client (encoder la chaîne en octets) conn.sendall(data) print(f"Renvoyé en écho à {addr}")
except socket.error as e: print(f"Erreur de socket : {e}") except KeyboardInterrupt: print("\nArrêt du serveur.")
if __name__ == "__main__": run_server()Un Simple Client Écho TCP
Section titled “Un Simple Client Écho TCP”Ce client se connecte au serveur, envoie un message et affiche la réponse renvoyée en écho.
#!/usr/bin/env python3import socket
HOST = '127.0.0.1' # Nom d'hôte ou adresse IP du serveurPORT = 65432 # Le port utilisé par le serveur
def run_client(message): try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((HOST, PORT)) print(f"Connecté au serveur {HOST}:{PORT}")
# Encoder le message en octets avant l'envoi message_bytes = message.encode('utf-8') s.sendall(message_bytes) print(f"Envoyé : {message}")
# Recevoir les données renvoyées en écho data = s.recv(1024) # Décoder les octets reçus en chaîne de caractères received_message = data.decode('utf-8') print(f"Écho reçu : {received_message}")
except socket.error as e: print(f"Erreur de socket : {e}") except ConnectionRefusedError: print(f"Connexion refusée. Le serveur est-il en cours d'exécution sur {HOST}:{PORT} ?")
if __name__ == "__main__": message_to_send = "Hello, Server!" run_client(message_to_send)Exécution du Serveur et du Client :
Section titled “Exécution du Serveur et du Client :”- Ouvrez un terminal et exécutez le serveur :
python server.py - Ouvrez un autre terminal et exécutez le client :
python client.py
Sortie du Serveur :
Server listening on 127.0.0.1:65432Connected by ('127.0.0.1', <client_port>)Received from ('127.0.0.1', <client_port>): Hello, Server!Echoed back to ('127.0.0.1', <client_port>)Client ('127.0.0.1', <client_port>) disconnected.Sortie du Client :
Connected to server 127.0.0.1:65432Sent: Hello, Server!Received echo: Hello, Server!Modules Internet de Haut Niveau en Python
Section titled “Modules Internet de Haut Niveau en Python”La bibliothèque standard de Python inclut des modules pour les protocoles Internet courants :
| Protocole | Usage Principal | Port(s) Courant(s) | Module(s) Python |
|---|---|---|---|
| HTTP/HTTPS | Accès web | 80, 443 | urllib.request, http.client (Niveau inférieur). requests (Tiers, recommandé) |
| FTP | Transfert de fichiers | 21 | ftplib |
| SMTP | Envoi d’e-mails | 25, 587, 465 | smtplib |
| POP3 | Récupération d’e-mails | 110, 995 | poplib |
| IMAP4 | Récupération d’e-mails | 143, 993 | imaplib |
| NNTP | Actualités Usenet | 119, 563 | nntplib |
| Telnet | Connexion à distance | 23 | telnetlib |
| XML-RPC | Appels de procédure à distance | Variable | xmlrpc.client, xmlrpc.server |
Pour les interactions web (HTTP/HTTPS), la bibliothèque tierce requests est largement utilisée et généralement préférée à urllib pour son API plus simple.
Pour aller plus loin
Section titled “Pour aller plus loin”La programmation de sockets est un sujet vaste. Explorez ces ressources :
- Documentation Officielle du Module
socketde Python : https://docs.python.org/3/library/socket.html - Tutoriel sur la Programmation de Sockets en Python : https://docs.python.org/3/howto/sockets.html
- Guide de Beej sur la Programmation Réseau (Guide C général, les concepts s’appliquent) : https://beej.us/guide/bgnet/