mardi 13 novembre 2012

Client Serveur Tcp en python

Aujourd'hui, je vais vous montrer comment réaliser simplement un client et un serveur tcp en python.

Tout d'abord, voici le code du client:
import socket

def sendMsg(s,msg):
    s.send(bytes(msg,'utf-8'))

def receiveMsg(s):
    rec=s.recv(1024).strip()
    return rec.decode('utf-8')

s = socket.socket()
host = socket.gethostname()
port = 9999
s.connect((host,port))
rec=receiveMsg(s)
print(rec)
while True:
    text=input(">")
    if text == "quit":
        s.close()
        quit()
    sendMsg(s,text)
    rec=receiveMsg(s)
    print(rec)



Très simple, j'utilise ici la libraire standard socket. Cette librairie apporte les fonctions de base de la communication tcp, à savoir l'écoute d'un port, la création d'une connexion, sa fermeture et l'envoie et réception de données. Je définis tout d'abord mes deux fonctions de réception et d'envoi. Il est préférable pour préserver l'intégrité des données d'envoyer les chaines en bytes. la fonction d'envoie convertie donc une chaine en utf-8 en bytes et la fonction de réception fait l'inverse.
Ensuite, nous avons la création de notre socket. On définit par la suite les paramètres de connexion, le serveur et le port puis on établie la connexion.
Le client attends un message du serveur, ensuite l'utilisateur peut entrer du texte qui sera envoyé au serveur qui attendra une réponse et ainsi de suite.
Si certains sont intéressés, je pourrais publier une version améliorer nécessitant une connexion avec login et mot de passe et une version threadée.

Le serveur n'est pas beaucoup plus complexe.
import socket

def sendMsg(c,msg):
    c.send(bytes(msg,'utf-8'))

def receiveMsg(c):
    rec=c.recv(1024).strip()
    return rec.decode('utf-8')

s = socket.socket()
host= socket.gethostname()
port = 9999
s.bind((host,port))

s.listen(5)
while True:
    c,addr = s.accept()
    print('Got connection from '+str(addr))
    sendMsg(c,"Welcome")
    while True:
        rec=receiveMsg(c)
        if len(rec) > 0:
        sendMsg(c,"message reçu")
        else:
            print("client deconnecte")
            c.close() 

Même méthode que pour le client, je définis mes fonctions d'envoi et de réception. Ensuite j'ouvre ma socket sur le serveur et le port définit. Si un client se connecte, je lui envoie Welcome. Il peut ensuite me renvoyer du texte auquel le serveur répondra par un "message reçu".

Beaucoup de docs utilisent la librairie socketserver qui bien que très pratique, peu parfois être insuffisante. Avec ce client/server fait maison, je contrôle tout et peut le faire évoluer à ma guise sans être bloquer par la méthode handle.
Prochaine étape, l'échange de fichiers à travers ce même client/server et peut-être un jour le streaming.


6 commentaires:

  1. Bonjour je suis débutant en Phyton je test votre code serveur et le client sous Phyton 3.3.2

    J'arrive à me connecter au serveur, le serveur répond welcome et aprés plus rien ...

    RépondreSupprimer
  2. Bonjour,
    Normalement le serveur doit répondre qu'il a bien reçu le message que vous envoyez.
    Je n'ai pas testé en 3.3 mais ça devrait fonctionner de la même manière.
    Avez-vous une erreur? Voyez-vous le ">" côté client après le Welcome?

    RépondreSupprimer
  3. Bonjour,
    Alors j'ai bien le Welcome ensuite j'ai le > je tape un text ensuite Enter cela passe à ligne et rien
    sur le serveur j'ai bien got connection from ... et ensuite plus rien

    Cordialement,
    bypbop

    RépondreSupprimer
  4. A quoi correspond le 5 dans s.listen(5) ?

    Cordialement,
    bypbop

    RépondreSupprimer
    Réponses
    1. Il définit le nombre maximum de connections simultanées que le serveur accepte.
      Il faudrait rajouter un
      Print(rec)
      Juste après le rec=receiveMsg(c)
      Cela permettrait de vérifier que le serveur a bien reçu le message

      Supprimer
  5. Ok je viens de comprendre mon erreur je ne savais pas qu'il fallait respecter l'indentation en Python
    autant pour moi ;-)

    Merci pour votre aide précieuse.

    RépondreSupprimer