Reseau::py

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
Fiche express
Domaine Programmation réseau par sockets
Modules socket, select
Voir aussi Rappel python · Test de penetration

Reseau::py présente la programmation réseau en Python avec le module socket : construction d'un socket, mise en écoute côté serveur, connexion côté client, échange de messages, puis un serveur multi-clients à l'aide de select.

Cycle de vie d'un socket

Construire un socket TCP :

import socket
connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Attacher (bind), écouter (5 connexions en attente), accepter :

connexion_principale.bind(('', 12800))
connexion_principale.listen(5)
connexion_avec_client, info_connexion = connexion_principale.accept()

Côté client :

import socket
connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_avec_serveur.connect(('localhost', 12800))

Communiquer, puis fermer :

connexion_avec_client.send(b"Je viens d'accepter la connexion")
msg_recu = connexion_avec_serveur.recv(1024)

connexion_avec_client.close()   # côté serveur
connexion_avec_serveur.close()  # côté client

Exemple : le serveur

import socket

hote = ''
port = 12800

connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_principale.bind((hote, port))
connexion_principale.listen(5)

print("Le serveur écoute à présent sur le port {}".format(port))

connexion_avec_client, infos_connexion = connexion_principale.accept()

msg_recu = b""
while msg_recu != b"fin":
    msg_recu = connexion_avec_client.recv(1024)
    print(msg_recu.decode())
    connexion_avec_client.send(b"5 / 5")

print("fermeture de la connexion")
connexion_avec_client.close()
connexion_principale.close()

Exemple : le client

import socket

hote = 'localhost'
port = 12800

connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_avec_serveur.connect((hote, port))
print("Connexion établie avec le serveur sur le port {}".format(port))

msg_a_envoyer = b""
while msg_a_envoyer != b"fin":
    msg_a_envoyer = input("> ")
    msg_a_envoyer = msg_a_envoyer.encode()
    connexion_avec_serveur.send(msg_a_envoyer)
    msg_recu = connexion_avec_serveur.recv(1024)
    print(msg_recu.decode())

print("Fermeture de la connexion")
connexion_avec_serveur.close()

Serveur multi-clients avec select

import socket
import select

hote = ''
port = 12800

connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_principale.bind((hote, port))
connexion_principale.listen(5)

print("Le serveur écoute à présent sur le port {}".format(port))

serveur_lance = True
clients_connectes = []

while serveur_lance:
    connexions_demandees, wlist, xlist = select.select([connexion_principale], [], [], 0.05)

    for connexion in connexions_demandees:
        connexion_avec_client, infos_connexion = connexion.accept()
        clients_connectes.append(connexion_avec_client)

    clients_a_lire = []
    try:
        clients_a_lire, wlist, xlist = select.select(clients_connectes, [], [], 0.05)
    except select.error:
        pass
    else:
        for client in clients_a_lire:
            msg_recu = client.recv(1024)
            msg_recu = msg_recu.decode()
            print("reçu {}".format(msg_recu))
            client.send(b"5 / 5")
            if msg_recu == "fin":
                serveur_lance = False

print("Fermeture des connexions")
for client in clients_connectes:
    client.close()

connexion_principale.close()

Voir aussi