Outils pour utilisateurs

Outils du site


client-serveur_tcp_stream

Clients-serveurs TCP utilisant StreamRequestHandler du module SocketServer

Généralités

Il s'agit d'une version 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.

Le principal avantage de cette version StreamRequestHandler par rapport à la version BaseRequestHandler est que les échanges sont traités comme un flux de fichier, ce qui permet de ne pas avoir à gérer soi-même de buffer.

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 en mode 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 StreamRequestHandler 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
adresse=('', 20000)
 
##############################################################################
class Traitementrequete(SocketServer.StreamRequestHandler):
 
    def handle(self):
 
        # lecture de la requête et suppression des caractères de fin de ligne
        requete = self.rfile.readline().rstrip('\r\n')
 
        # préparation de la réponse
        try:
            reponse = "%s" % eval(requete)
        except:
            reponse = "%s" % sys.exc_info()[1]
 
        # envoi de la réponse avec ajout des caractères de fin de ligne
        self.wfile.write("%s\r\n" % 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 en mode 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 StreamRequestHandler 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
adresse=('', 20000)
 
##############################################################################
class Traitementrequete(SocketServer.StreamRequestHandler):
 
    def handle(self):
 
        # lecture de la requête et suppression des caractères de fin de ligne
        requete = self.rfile.readline().rstrip('\r\n')
 
        # préparation de la réponse
        try:
            reponse = "%s" % eval(requete)
        except:
            reponse = "%s" % sys.exc_info()[1]
 
        # envoi de la réponse avec ajout des caractères de fin de ligne
        self.wfile.write("%s\r\n" % 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 en mode asynchrone multiprocessus

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 utilisant StreamRequestHandler 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
adresse=('', 20000)
 
##############################################################################
class Traitementrequete(SocketServer.StreamRequestHandler):
 
    def handle(self):
 
        # lecture de la requête et suppression des caractères de fin de ligne
        requete = self.rfile.readline().rstrip('\r\n')
 
        # préparation de la réponse
        try:
            reponse = "%s" % eval(requete)
        except:
            reponse = "%s" % sys.exc_info()[1]
 
        # envoi de la réponse avec ajout des caractères de fin de ligne
        self.wfile.write("%s\r\n" % 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 TCP "StreamRequestHandler"
 
import socket
 
buf=1024
adresse=('192.168.0.200', 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
            maSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            try:
                maSocket.connect(adresse)
            except:
                print "impossible d'etablir la connexion"
                break
 
            # envoi de la requête
            envoi = maSocket.send("%s\r\n" % requete)
 
            # réception de la réponse
            reponse = maSocket.recv(buf).rstrip("\r\n")
 
            # traitement de la réponse
            print '=> "%s"' % reponse
 
            # arrêter la connexion
            maSocket.close()

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

Outils de la page