#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

import socket
import select
import time

class Serveur:
    """ La classe serveur, une fois instanciée elle lance le serveur """
    
    def __init__(self):
        """ Initialisation de la classe """
        self.TAILLE_BLOC=32 # la taille des blocs d'emission receptions
        self.CumulData=''   # Les données cumulées de tout le monde
        self.preaders=[]    # la liste des socket potentiellement lisibles
        self.pwriters=[]    # la liste des socket sur lesquelles on peut ecrire

        # creation de la connection pour le serveur
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
        sock.bind(('',int(sys.argv[1])))
        sock.listen(5)
    
        # on met la socket en mode non bloquant
        sock.setblocking(0)
        # on ajoute la socket principale dans la liste des sockets que
        # l'on peut lire. On pourra ainsi détecter qu'un client se connecte
        self.preaders.append(sock)

        # Boucle principale
        while 1:
            # on récupère l'ensemble des socket sur lesquelles on peut lire
            # puis sur lesquelles on peut écrire
            # Le select répondra quoiqu'il arrive dans 30 secondes au plus
            oktoread, oktowrite, pendingerr = \
                     select.select(self.preaders, self.pwriters, [], 30.0)

             # on traite les sockets lisibles
            for clisock in oktoread:
                if clisock == sock:
                    # si c'est la socket principale,
                    # c'est qu'un client se connecte
                    newsock, addr = sock.accept()
                    print 'connection entrante : %s:%d' % addr
                    self.preaders.append(newsock)
                    self.pwriters.append(newsock)
                else :
                     # sinon on lit ce que la socket a écrit
                    self.lit(clisock)
    
            # si au moins un client a parlé alors
            if self.CumulData:
                # on renvoie l'info à tout le monde
                for clisock in oktowrite:
                    self.ecrit(clisock)
                self.CumulData=''

    def lit(self,sock):
        """ reçoit les données d'un client et vérifie qu'il est
        toujours connecté """
        print "lecture"
        data = sock.recv(self.TAILLE_BLOC)
        if data:
            print "reçut : ",data
            self.CumulData+=data
        else:
            # si je n'ai rien reçut c'est que le client s'est déconnecté
            self.preaders.remove(sock)
            self.pwriters.remove(sock)
    
    def ecrit(self,sock):
        print "j'envois :", self.CumulData
        sock.send(self.CumulData)
    
if __name__=="__main__":
    import sys
    if len(sys.argv)<2:
        print "usage : %s <port>" % (sys.argv[0],)
        sys.exit(-1)
    Serveur()
