Mis a jour le 2025-04-14, 12:10

Socket pour la communication réseau

Le module s'appelle socket : import socket.
Principales fonctions :
  • pour créer une socket aussi bien pour le serveur que pour le client : soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  • pour faire un bind sur un port donné (ici 8080), pour le serveur : soc.bind((monServeur, 8080)).
  • pour écouter sur le port, pour le serveur : soc.listen(1). Si ce n'est pas possible, une exception socket.error est générée.
  • pour accepter une connection d'un client, pour le serveur : (socClient, addrClient) = soc.accept() :
    • socClient est la socket qui permet de communiquer avec le client accepté.
    • addrClient est une paire (un tuple) avec l'hôte du client et le port source.
  • pour tenter une connection à un serveur sur un port, pour le client : soc.connect((monServeur, 8080)).
  • pour recevoir des données, aussi bien côté client que côté serveur, à concurrence de 2048 octets : data = soc.recv(2048). Utiliser une puissance de 2 comme nombre, souvent 4096.
  • pour envoyer des données, aussi bien côté client que côté serveur : soc.sendall(data).
  • pour mettre un timeout de 10 secondes par défaut sur toutes les nouvelles connections : socket.setdefaulttimeout(10). Sinon, après création de la socket mais avant tentative de connection, on peut appeler directement sur la socket créée : soc.settimeout(10).
  • pour fermer une socket : soc.close().
  • réutilisation d'un port :
    • si un port a été utilisé par un serveur qui vient d'être éteint, le port n'est pas immédiatement disponible, il faut attendre un certain timeout.
    • pour réutiliser immédiatement le port, mettre l'option : soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) avant de faire le bind.
  • timeout : quand un client essaie de faire une connection :
    • par défaut, si le serveur ne répond pas, il va attendre indéfiniment (l'ordre connect va bloquer).
    • on peut décider qu'après un certain temps, le client doit abandonner : pour cela, il suffit de faire soc.settimeout(10) pour qu'au bout de 10 secondes de tentatives, le client abandonne.
    • en cas d'abandon, une exception socket.timeout est lancée (une classe qui dérive de socket.error).
Exemple de code montrant un serveur et un client simples :
  • Le serveur qui sert les requêtes des clients les uns après les autres et ne termine jamais (le close final n'est en fait jamais exécuté) :
    soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    soc.bind(('localhost', 8080))
    soc.listen(1)
    while True:
        print('a l\'ecoute')
        (socClient, addrClient) = soc.accept()
        print('address du client', addrClient)
        try:
            while True:
                data = socClient.recv(2048)
                if data == '':
                    break
                print('donnees du client', data)
                socClient.sendall('ok')
            socClient.close()
        except socket.error:
            print('client interrompu')
    soc.close()
        
  • le client (on peut en lancer plusieurs en même temps, ils seront servis tour à tour) :
    client = str(os.getpid())
    print('je suis le client numero', client)
    soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    soc.connect(('localhost', 8080))
    soc.sendall('envoi1 au serveur du client ' + client)
    time.sleep(3)
    data = soc.recv(2048)
    print('recu : ', data)
    soc.sendall('envoi2 au serveur du client ' + client)
    data = soc.recv(2048)
    print('recu : ', data)
    soc.close()
        

Copyright python-simple.com
programmer en python, tutoriel python, graphes en python, Aymeric Duclert