Outils pour utilisateurs

Outils du site


client-serveur_tcp_base

Clients-serveurs TCP utilisant BaseRequestHandler du module SocketServer

Généralités

Il s'agit d'une version de base d'un “client-serveur TCP” déjà élaboré, pouvant être utilisé sur une même machine ou dans un réseau local TCP/IP sur plusieurs machines différentes.

Attention: le protocole réseau est TCP/IP, le même qu'Internet, mais ce n'est pas du “web”: un navigateur web ne sera pas un “client” correct.

Remarques:

  • il ne faut pas mélanger le serveur et le client dans la même page de code comme on le voit souvent dans les exemples sur le web.
  • il faut lancer l'exécution du serveur directement en console et pas avec un outil de développement.
  • on arrête le serveur seulement en “tuant” son processus.

Pour éviter d'avoir un exemple où on se contente de renvoyer la requête au demandeur, ce qui manque un peu d'intérêt, on donne ici l'exemple d'une mini calculatrice d'expressions mathématiques en utilisant eval(). Au moins, ça, c'est utile…

C'est encore un serveur très simple… Par contre, je ne sais pas ce que ça donne sur le plan sécurité réseau: à utiliser dans un réseau local protégé.


Le serveur TCP synchrone

Avec ce serveur synchrone, chaque requête doit attendre la fin de la requête précédente.

Le code est largement auto-documenté:

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
# Serveur TCP utilisant BaseRequestHandler du module SocketServer
 
# import nécessaire pour le fonctionnement du serveur
import SocketServer
 
# import seulement nécessaire pour l'exemple (=calcul d'expression par eval())
import sys
from math import *
 
# initialisation des variables globales
buf=1024
adresse=('', 20000)
 
##############################################################################
class Traitementrequete(SocketServer.BaseRequestHandler):
 
    def handle(self):
 
        # lecture de la requête
        requete = self.request.recv(buf)
 
        # préparation de la réponse
        try:
            reponse = "%s" % eval(requete)
        except:
            reponse = "%s" % sys.exc_info()[1]
 
        # renvoi de la réponse au demandeur
        self.request.send(reponse)
 
        return
 
##############################################################################
if __name__ == '__main__':
 
    serveur = SocketServer.TCPServer(adresse, Traitementrequete)
    print "serveur actif"
    serveur.serve_forever()
    # fermeture de connexion inutile: on arrête le serveur en "tuant" son processus
    #server.socket.close()


Le serveur TCP asynchrone multi-threads

Avec ce serveur, chaque requête est traitée dans un nouveau thread sans attendre la fin de la requête précédente.

Le code est largement auto-documenté:

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
# Serveur TCP utilisant BaseRequestHandler du module SocketServer
# chaque nouvelle requête sera traitée dans un nouveau thread
 
# import nécessaire pour le fonctionnement du serveur
import SocketServer
 
# imports seulement nécessaires pour l'exemple (=calcul d'expression par eval())
import sys
from math import *
 
# initialisation des variables globales
buf=1024
adresse=('', 20000)
 
##############################################################################
class Traitementrequete(SocketServer.BaseRequestHandler):
 
    def handle(self):
 
        # lecture de la requête
        requete = self.request.recv(buf)
 
        # préparation de la réponse
        try:
            reponse = "%s" % eval(requete)
        except:
            reponse = "%s" % sys.exc_info()[1]
 
        # renvoi de la réponse au demandeur
        self.request.send(reponse)
 
        return
 
##############################################################################
class Serveurthread(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass
 
##############################################################################
if __name__ == '__main__':
 
    serveur = Serveurthread(adresse, Traitementrequete)
    print "serveur actif"
    serveur.serve_forever()
    # fermeture de connexion inutile: on arrête le serveur en "tuant" son processus
    #server.socket.close()


Le serveur TCP asynchrone multi-processus (Linux)

Avec ce serveur, chaque requête est traitée dans un nouveau processus sans attendre la fin de la requête précédente.

Le code est largement auto-documenté:

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
# Serveur TCP asynchrone utilisant BaseRequestHandler du module SocketServer
# chaque nouvelle requête sera traitée dans un nouveau processus (Linux)
 
# import nécessaire pour le fonctionnement du serveur
import SocketServer
 
# imports seulement nécessaires pour l'exemple (=calcul d'expression par eval())
import sys
from math import *
 
# initialisation des variables globales
buf=1024
adresse=('', 20000)
 
##############################################################################
class Traitementrequete(SocketServer.BaseRequestHandler):
 
    def handle(self):
 
        # lecture de la requête
        requete = self.request.recv(buf)
 
        # préparation de la réponse
        try:
            reponse = "%s" % eval(requete)
        except:
            reponse = "%s" % sys.exc_info()[1]
 
        # renvoi de la réponse au demandeur
        self.request.send(reponse)
 
        return
 
##############################################################################
class Serveurthread(SocketServer.ForkingMixIn, SocketServer.TCPServer):
    pass
 
##############################################################################
if __name__ == '__main__':
 
    serveur = Serveurthread(adresse, Traitementrequete)
    print "serveur actif"
    serveur.serve_forever()
    # fermeture de connexion inutile: on arrête le serveur en "tuant" son processus
    #server.socket.close()


Le client TCP

Vous adaptez l'adresse à votre situation!

Le code est largement auto-documenté:

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
# client TCP fait pour communiquer avec un serveur utilisant BaseRequestHandler
 
import socket
 
buf=1024
adresse=('192.168.0.99', 20000)
 
##############################################################################
if __name__ == '__main__':
 
    while True:
        # saisie de la requete au clavier
        requete = raw_input("?: ").strip()
 
        # condition d'arrêt du client
        if requete=="":
            print "arret du client TCP"
            break
        else:
            # établissement de la connexion
            monSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            try:
                monSocket.connect(adresse)
            except:
                print "impossible d'etablir la connexion"
                break
 
            # envoi de la requête
            envoi = monSocket.send("%s" % requete)
 
            # réception de la réponse
            reponse = monSocket.recv(buf)
 
            # traitement de la réponse
            print '=> "%s"' % reponse
 
            # arrêter la connexion
            monSocket.close()

client-serveur_tcp_base.txt · Dernière modification: 2008/04/12 08:49 de tyrtamos

Outils de la page