Programmation de sockets en Python: un guide pour débutants

Aditya Raj 10 octobre 2023
  1. Comment implémenter la programmation de sockets en Python
  2. Comment créer un serveur dans la programmation de sockets en Python
  3. Programmation de socket avec le protocole UDP en Python
  4. Conclusion
Programmation de sockets en Python: un guide pour débutants

Normalement, lorsque nous écrivons un programme, nous n’avons pas besoin de communiquer avec d’autres programmes ou ordinateurs.

Cependant, nous pourrions avoir besoin de communiquer avec d’autres ordinateurs pour créer des applications de messagerie ou d’autres applications avec une architecture serveur-client. Pour créer de telles applications, nous pouvons utiliser la programmation par socket en Python.

Cet article abordera les bases de la programmation de sockets en Python. Nous allons également implémenter séparément une application de messagerie simple utilisant la programmation par socket avec les protocoles TCP et UDP.

Que sont les sockets en Python

Lorsque deux applications ou processus interagissent, ils utilisent un canal de communication spécifié. Les sockets sont les extrémités ou les points d’entrée de ces canaux de communication.

Nous pouvons utiliser des sockets pour établir un canal de communication entre deux processus, au sein d’un processus ou entre des processus sur différentes machines. Il existe différents types de sockets comme les sockets TCP, les sockets UDP et les sockets de domaine UNIX.

Comment implémenter la programmation de sockets en Python

Python nous fournit le module socket pour implémenter la programmation socket. Le module socket fait partie de la bibliothèque Python standard et fournit toutes les fonctions et méthodes à l’aide desquelles vous pouvez créer des sockets en Python.

Vous n’avez pas besoin de télécharger explicitement le module socket dans votre machine, et vous pouvez l’importer directement dans votre programme en utilisant l’instruction d’importation comme suit.

import socket

Pour implémenter la programmation par socket, nous devons créer deux processus qui communiqueront à l’aide du socket.

L’un des programmes fonctionne en tant que serveur et l’autre en tant que client. Le serveur et le client ont des fonctionnalités différentes. Par conséquent, nous utilisons différentes fonctions lors de la création de processus serveur et client.

Voyons comment créer un serveur et un processus client un par un.

Comment créer un serveur dans la programmation de sockets en Python

Pour créer un serveur, nous allons d’abord créer un socket. Pour cela, nous utilisons la méthode socket().

Créer un socket : la méthode socket()

La syntaxe de la méthode socket() est la suivante.

socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, fileno=None)

Ici,

  • Le paramètre famille représente la famille d’adresses à laquelle appartient une socket. Par défaut, il s’agit de AF_INET et crée une socket avec une adresse de protocole Internet version 4 (IPv4). Vous pouvez utiliser d’autres familles d’adresses comme AF_UNIX pour l’adresse UNIX et AF_INET6 pour l’adresse du protocole Internet version 6 (IPv6).
  • Le paramètre type désigne le type de socket. Par défaut, il a la valeur SOCK_STREAM indiquant que le socket suivra le protocole TCP orienté connexion. Vous pouvez utiliser SOCK_DGRAM pour créer des sockets de datagramme qui suivent le protocole UDP.
  • Le paramètre proto désigne le numéro de protocole, et il est généralement 0. Si vous utilisez la famille d’adresses AF_CAN dans la famille de paramètres, le numéro de protocole doit être l’un des CAN_RAW, CAN_BCM, CAN_ISOTP ou CAN_J1939.
  • Le paramètre fileno contient la valeur par défaut None. Si nous spécifions un descripteur de fichier dans fileno, les valeurs des paramètres family, type et proto sont automatiquement détectées à partir du descripteur de fichier.

Après avoir créé un socket, nous le lions à une adresse et un numéro de port en utilisant la méthode bind().

Lier le socket à une adresse : la méthode bind()

En utilisant la fonction socket(), la méthode bind() est invoquée sur l’objet socket que nous avons créé.

Il prend un tuple contenant l’adresse à laquelle la socket sera liée. Le format de l’adresse peut varier selon la famille d’adresses que vous avez choisie. Nous allons créer une socket avec la famille d’adresse AF_INET. Ainsi, l’adresse contiendra le nom d’hôte et le numéro de port.

La syntaxe de la méthode bind() est la suivante.

bind((hostname, port))

Vous pouvez spécifier explicitement le hostname. Si vous créez le serveur sur la machine locale, vous pouvez spécifier le nom d’hôte comme localhost ou 127.0.0.1, la valeur par défaut pour l’adresse localhost.

Alternativement, vous pouvez utiliser la méthode gethostname() pour obtenir le nom d’hôte. Pour le paramètre port, vous pouvez utiliser n’importe quel numéro de port supérieur à 1024 et inférieur à 65535.

Après avoir lié le socket à une adresse, le serveur écoute les demandes de connexion du client. Pour cela, nous utilisons la méthode listen().

Écoutez les connexions : la méthode listen()

La syntaxe de la méthode listen() est la suivante.

listen(backlog)

Ici, le paramètre backlog désigne le nombre maximum de connexions non acceptées que le système autorisera avant de refuser de nouvelles connexions.

Après avoir exécuté la méthode listen(), le serveur est prêt à accepter les connexions.

Accepter une demande de connexion : la méthode accept()

Le serveur fonctionne constamment dans une boucle infinie et écoute les demandes des clients pour accepter une connexion d’un client. Une fois qu’une requête client est trouvée, le serveur accepte la requête en utilisant la méthode accept().

La méthode accept() renvoie un tuple (client, address). Ici, client représente un nouvel objet socket que nous utilisons pour envoyer et recevoir des messages. L’address est l’endroit où le socket client est lié.

Communiquer avec le client : méthodes send() et recv()

Après avoir accepté la connexion, le serveur peut communiquer avec le client.

Nous utilisons la méthode send() pour envoyer un message au client. La méthode send() est invoquée sur l’objet client retourné par la méthode accept().

Nous utilisons la méthode recv() pour recevoir les messages. La méthode recv(), lorsqu’elle est invoquée sur l’objet client, accepte un nombre représentant le nombre maximum d’octets qu’elle peut lire à partir de la connexion. Après exécution, il renvoie les données lues à partir de la connexion.

Une fois toutes les opérations terminées, nous devons fermer la connexion. Pour cela, nous invoquons la méthode close() sur l’objet client renvoyé par la méthode accept().

Après avoir discuté de toutes les méthodes requises pour créer un serveur, créons un processus serveur.

import socket

mySocket = socket.socket(
    family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, fileno=None
)
print("Socket created.")
hostname = "localhost"
portno = 9999
mySocket.bind((hostname, portno))
print("Socket bound to address {} and port number {}".format(hostname, portno))
mySocket.listen(5)
print("Listening for client.")
while True:
    client, client_addr = mySocket.accept()
    print("Connection established with client at address {}".format(client_addr))
    msg = client.recv(1024).decode()
    print("Message received from the client:")
    print(msg)
    print("Sending acknowledgment to the client.")
    msg_out = "Message received: {}. Thank you.".format(msg).encode()
    client.send(msg_out)
    print("Terminating the connection.")
    client.close()
    break

Maintenant que nous avons créé un serveur, créons un processus client qui communiquera avec le serveur.

Comment créer un client dans la programmation par socket

Pour créer un client, nous devons d’abord créer une socket avec la méthode socket() comme nous l’avons fait lors de la création du serveur. N’oubliez pas que les protocoles définis pour le socket client doivent être les mêmes que pour le socket serveur. Sinon, le programme ne fonctionnera pas comme vous le souhaitez.

Après avoir créé le socket, nous devons le connecter au serveur. Pour cela, nous allons utiliser la méthode connect().

Se connecter au serveur : la méthode connect()

La syntaxe de la méthode connect() est la suivante.

connect((host, port))

Ici, le paramètre host désigne l’adresse du serveur. Le paramètre port indique le numéro de port sur lequel le socket du serveur est créé. Vous devez donner les mêmes valeurs en entrée aux paramètres d’hôte et de port que vous avez fournis à la méthode bind() lors de la création du serveur.

Communication avec le serveur

Après vous être connecté au serveur, vous pouvez communiquer avec le serveur en utilisant les méthodes send() et recv(). Enfin, cela aiderait à fermer la connexion côté client en utilisant la méthode close().

Voici le programme client que nous utiliserons pour créer un processus client.

import socket

mySocket = socket.socket(
    family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, fileno=None
)
print("Socket created.")
hostname = "localhost"
portno = 9999
mySocket.connect((hostname, portno))
print("Connection established with the server.")
msg = "Hi I am a TCP client created by Aditya."
print("Sending msg to the server:", msg)
mySocket.send(msg.encode())
msg_in = mySocket.recv(1024).decode()
print("Acknowledgment received from the server:")
print(msg_in)
print("Terminating the Connection.")
mySocket.close()

Après avoir créé le serveur et le client, exécutons maintenant les programmes. N’oubliez pas que vous devez exécuter simultanément le programme client et le programme serveur afin que les deux processus puissent fonctionner simultanément et communiquer entre eux.

La sortie dans le terminal avec le programme serveur ressemblera à ceci :

Socket created.
Socket bound to address localhost and port number 9999
Listening for client.
Connection established with client at address ('127.0.0.1', 37958)
Message received from the client:
Hi I am a TCP client created by Aditya.
Sending acknowledgment to the client.
Terminating the connection.

La sortie dans le terminal avec le programme client ressemblera à ceci :

Socket created.
Connection established with the server.
Sending msg to the server: Hi I am a TCP client created by Aditya.
Acknowledgment received from the server:
Message received: Hi I am a TCP client created by Aditya.. Thank you.
Terminating the Connection.

Programmation de socket avec le protocole UDP en Python

Dans les sections précédentes, nous avons créé des sockets qui suivent le protocole TCP dans la connexion. Dans le protocole TCP, la connexion entre le client et le serveur est maintenue tout au long de la communication.

Cependant, il existe de nombreuses situations où nous ne pouvons pas maintenir une connexion stable entre le client et le serveur en raison de contraintes de ressources. Par conséquent, nous avons besoin d’un protocole de communication qui ne nécessite pas de connexion stable. Pour cela, nous utilisons le protocole UDP.

Comment créer un serveur avec le protocole UDP en Python

Pour créer une connexion avec le protocole UDP, nous devons suivre les étapes suivantes lors de la mise en œuvre du serveur.

  • Spécifiez SOCK_DGRAM dans l’entrée du paramètre type lors de la création du socket serveur avec la méthode socket().
  • Liez la socket à une adresse et un numéro de port en utilisant la méthode bind().
  • Comme nous n’avons pas besoin d’établir une connexion avec le client, nous n’utilisons pas les méthodes listen() et accept() pour établir la connexion. Nous pouvons directement commencer à communiquer avec le client.
  • Pour recevoir un message dans le protocole UDP, on utilise la méthode recvfrom(). Il prend le nombre d’octets à lire comme argument d’entrée et renvoie un tuple contenant les données et l’adresse à partir de laquelle les données ont été reçues.
  • Pour envoyer un message dans le protocole UDP, on utilise la méthode sendto(). La méthode sendto() prend les données comme premier argument d’entrée et un tuple contenant le nom d’hôte et le numéro de port comme adresse de la socket à laquelle les données seront envoyées.
  • Après communication, vous devez fermer le socket en utilisant la méthode close().

À l’aide du programme Python suivant, vous pouvez implémenter un processus serveur qui communique avec le protocole UDP.

import socket

mySocket = socket.socket(
    family=socket.AF_INET, type=socket.SOCK_DGRAM, proto=0, fileno=None
)
print("Socket created.")
hostname = "localhost"
portno = 9999
mySocket.bind((hostname, portno))
print("Socket bound to address {} and port number {}".format(hostname, portno))
while True:
    msg, client_addr = mySocket.recvfrom(1024)
    print("Message received from the client:")
    print(msg.decode())
    print("Sending acknowledgment to the client.")
    msg_out = "Message received: {}. Thank you.".format(msg).encode()
    mySocket.sendto(msg_out, client_addr)
    mySocket.close()
    break

Comment créer un client avec le protocole UDP en Python

Pour créer un processus client qui suit le protocole UDP, nous devons créer le socket en spécifiant SOCK_DGRAM dans l’entrée du paramètre type lors de la création du socket serveur avec la méthode socket(). Nous n’avons pas besoin d’utiliser la méthode connect() ici car nous n’avons pas besoin de créer une connexion.

Après avoir créé le socket, nous pouvons directement commencer à communiquer avec le serveur en utilisant les méthodes sendto() et recvfrom(). Après avoir communiqué avec le serveur, n’oubliez pas de fermer le socket en utilisant la méthode close().

À l’aide du programme Python suivant, vous pouvez implémenter un processus client qui communique avec le protocole UDP.

import socket

mySocket = socket.socket(
    family=socket.AF_INET, type=socket.SOCK_DGRAM, proto=0, fileno=None
)
print("Socket created.")
while True:
    msg = "Hi I am a UDP client created by Aditya."
    print("Sending msg to the server:", msg)
    mySocket.sendto(msg.encode(), ("localhost", 9999))
    msg_in = mySocket.recv(1024).decode()
    print("Acknowledgment received from the server:")
    print(msg_in)
    print("Terminating the Connection.")
    mySocket.close()
    break

Encore une fois, pour observer la sortie, vous devez exécuter simultanément le programme client et le programme serveur afin que les deux processus puissent être actifs en même temps et puissent communiquer entre eux.

La sortie dans le terminal avec le programme serveur ressemblera à ceci :

Socket created.
Socket bound to address localhost and port number 9999
Message received from the client:
Hi I am a UDP client created by Aditya.
Sending acknowledgment to the client.

La sortie dans le terminal avec le programme client ressemblera à ceci :

Socket created.
Sending msg to the server: Hi I am a UDP client created by Aditya.
Acknowledgment received from the server:
Message received: b'Hi I am a UDP client created by Aditya.'. Thank you.
Terminating the Connection.

Conclusion

Dans cet article, nous avons discuté de la programmation des sockets en Python. Nous avons également implémenté des programmes client et serveur séparément en utilisant les protocoles TCP et UDP pour apprendre les bases de la programmation de socket en Python.

TCP est orienté connexion et donc un protocole fiable. Lors de l’utilisation du protocole TCP, il est garanti que les messages iront du serveur au client et vice versa. Dans UDP, il n’est pas garanti que le message soit livré à la destination souhaitée.

D’autre part, le protocole UDP est plus rapide et facile à mettre en œuvre, tandis que le protocole TCP est plus lent. De plus, le protocole TCP ne peut pas être utilisé pour la diffusion, alors que nous pouvons utiliser le protocole UDP pour la diffusion.

En fonction des ressources disponibles et de vos besoins, vous pouvez choisir n’importe quel protocole pour implémenter la communication client-serveur à l’aide de sockets.

Auteur: Aditya Raj
Aditya Raj avatar Aditya Raj avatar

Aditya Raj is a highly skilled technical professional with a background in IT and business, holding an Integrated B.Tech (IT) and MBA (IT) from the Indian Institute of Information Technology Allahabad. With a solid foundation in data analytics, programming languages (C, Java, Python), and software environments, Aditya has excelled in various roles. He has significant experience as a Technical Content Writer for Python on multiple platforms and has interned in data analytics at Apollo Clinics. His projects demonstrate a keen interest in cutting-edge technology and problem-solving, showcasing his proficiency in areas like data mining and software development. Aditya's achievements include securing a top position in a project demonstration competition and gaining certifications in Python, SQL, and digital marketing fundamentals.

GitHub

Article connexe - Python Socket

Article connexe - Python Module