diff options
Diffstat (limited to 'TCP_Server_thread_Stream.py')
-rw-r--r-- | TCP_Server_thread_Stream.py | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/TCP_Server_thread_Stream.py b/TCP_Server_thread_Stream.py new file mode 100644 index 0000000..93cf2ee --- /dev/null +++ b/TCP_Server_thread_Stream.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# TCP_Server_thread_Stream.py por: +# Flavio Danesse <fdanesse@gmail.com> +# CeibalJAM! - Uruguay - Plan Ceibal +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import time +import socket +import threading +import SocketServer + +import time +from SocketServer import StreamRequestHandler +from SocketServer import ThreadingTCPServer + +import Variables as ESPEJO + +class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.ThreadingTCPServer): + ''' Servidor Multihilo para conexiones simultáneas. ''' + pass + ''' + __init__(self, server_address, RequestHandlerClass) from TCPServer + fileno(self) from TCPServer + finish_request(self, request, client_address) from TCPServer + get_request(self) from TCPServer + handle_error(self, request, client_address) from TCPServer + handle_request(self) from TCPServer + process_request(self, request, client_address) from ThreadingMixIn + serve_forever(self) from TCPServer + server_activate(self) from TCPServer + server_bind(self) from TCPServer + verify_request(self, request, client_address) from TCPServer + ''' + ''' + def __init__(self, server_address, handler_class=None): + SocketServer.TCPServer.__init__(self, server_address, handler_class) + return + + def server_activate(self): + SocketServer.TCPServer.server_activate(self) + return + + def serve_forever(self): + while True: + self.handle_request() + return + + def handle_request(self): + return SocketServer.TCPServer.handle_request(self) + + def verify_request(self, request, client_address): + return SocketServer.TCPServer.verify_request(self, request, client_address) + + def process_request(self, request, client_address): + return SocketServer.TCPServer.process_request(self, request, client_address) + + def server_close(self): + return SocketServer.TCPServer.server_close(self) + + def finish_request(self, request, client_address): + return SocketServer.TCPServer.finish_request(self, request, client_address) + + def close_request(self, request_address): + return SocketServer.TCPServer.close_request(self, request_address) ''' + +class ThreadedTCPRequestHandler(SocketServer.StreamRequestHandler): + ''' Atiende y procesa todas las conexiones entrantes + __del__(self) from BaseRequestHandler + __init__(self, request, client_address, server) from BaseRequestHandler + finish(self) + handle(self) from BaseRequestHandler + setup(self) + def __init__(self, request, client_address, server): + SocketServer.StreamRequestHandler.__init__(self, request, client_address, server) + return ''' + + def handle(self): + # Acepta la conexión de un jugador + while 1: + try: + datos = self.request.recv(200) + self.recibir_datos(datos) + self.enviar_datos() + + except socket.error, e: + print "Error en Handle del Server: ", "Error %s" % (e) + self.request.close() + return + + def recibir_datos(self, datos): + # Recibe los datos del jugador conectado + mensajes = str(datos).split(ESPEJO.TERMINATOR) + #print "Datos Recibidos en Servidor: ", mensajes + + for mensaje in mensajes: + valores = mensaje.split() + if "T" in valores: + # Se recibe un tanque + try: + # para evitar que falle si no vienen todos los datos + nombre, angulo, x, y = int(valores[0]), int(valores[2]), int(valores[3]), int(valores[4]) + self.procesar_datos_tanques(nombre=nombre, angulo=angulo, x=x, y=y) + except: + return + + elif "B" in valores: + # Se recibe una bala + try: + angulo, x, y = int(valores[2]), int(valores[3]), int(valores[4]) + self.procesar_datos_balas(angulo=angulo, x=x, y=y) + except: + return + + elif "D" in valores: + # self.procesar_datos_puntos(mensaje) + # mensaje_puntos = "%s %s %s%s" % ("D", self.energia, self.puntaje, TERMINATOR) + energia, puntaje = int(valores[1]), int(valores[2]) + self.procesar_datos_puntos(energia=energia, puntaje=puntaje) + + elif "P" in valores: + # simple presencia en la red + pass + + else: + #print "Recibiendo Otras Cosas: ", mensaje, "***" + pass + + # ---------------------inicio PERSISTENCIA DE DATOS ----------------------------------- + def procesar_datos_puntos(self, energia=100, puntaje=0): + # hay cambios de puntaje o energía + ESPEJO.Tanques[self.client_address[0]].set_puntos(energia=energia, puntaje=puntaje) + ESPEJO.Tanques[self.client_address[0]].set_jugadores_por_informar_puntaje(ESPEJO.Tanques.keys()) + + def procesar_datos_balas(self, angulo=0, x=0, y=0): + # ha llegado una bala + ESPEJO.Tanques[self.client_address[0]].set_bala(angulo=angulo, x=x, y=y) # crea la bala + ESPEJO.Tanques[self.client_address[0]].set_jugadores_por_informar_disparo(ESPEJO.Tanques.keys()) + # pasa la lista de todos los jugadores para informar del disparo, a medida que se informa, se eliminan de la lista + + def procesar_datos_tanques(self, nombre=None, angulo=0, x=0, y=0): + # Actualiza los datos del tanque de este jugador. Si el Jugador no existe, lo agrega. + if nombre == None: + # si no hay nombre no puede procesarse + return + + if not self.client_address[0] in ESPEJO.Tanques.keys(): + # Si no existe, se agrega + ESPEJO.Tanques[self.client_address[0]] = ESPEJO.Tanque(nombre) + ESPEJO.Tanques[self.client_address[0]].set_datos_tanque(nombre=nombre, angulo=angulo, x=x, y=y) + else: + # Si existe se actualiza + ESPEJO.Tanques[self.client_address[0]].set_datos_tanque(nombre=nombre, angulo=angulo, x=x, y=y) + # ---------------------fin PERSISTENCIA DE DATOS ----------------------------------- + + def enviar_datos(self): + # A quien se conectó se le envían los datos de todos, también los suyos. + + mensaje = "" + for jugador in ESPEJO.Tanques.values(): # para todos los jugadores. + mensaje += jugador.get_datos_tanque() # obtener las posiciones de tanques. + + bala = jugador.get_bala() + if bala != None and self.client_address[0] in jugador.jugadores_por_informar_disparo: + # Si hay una bala en juego de este jugador y el que se ha conectado no ha sido informado: + mensaje += bala + jugador.jugadores_por_informar_disparo.remove(self.client_address[0]) # borrar de la lista, ya se le informó + if not jugador.jugadores_por_informar_disparo: jugador.bala = None + + if jugador.jugadores_por_informar_puntaje: + if self.client_address[0] in jugador.jugadores_por_informar_puntaje: + # Si hay cambios de puntaje y el que se ha conectado no ha sido informado: + mensaje += jugador.get_puntos() + jugador.jugadores_por_informar_puntaje.remove(self.client_address[0]) # borrar de la lista, ya se le informó + + if self.client_address[0] in ESPEJO.Tanques.keys(): + # evitar error de escaner de red de los clientes + if ESPEJO.Tanques[self.client_address[0]].desconectados: + # si hay información de desconexión de algún jugador + mensaje += ESPEJO.Tanques[self.client_address[0]].desconectados + ESPEJO.Tanques[self.client_address[0]].desconectados = "" + + if len(mensaje) > ESPEJO.CARGA: + ESPEJO.CARGA = len(mensaje) + print "Carga en la red: ", ESPEJO.CARGA + self.request.send(mensaje) + + def setup(self): + # Llamado antes de la handle() para realizar acciones de inicialización necesaria. La implementación predeterminada no hace nada. + #print "Server Setup" + #return SocketServer.BaseRequestHandler.setup(self) + pass + + def finish(self): + # Llamado despues de la handle() para realizar cualquier método de limpieza. La implementación predeterminada no hace nada. + if self.client_address[0] in ESPEJO.Tanques.keys(): + # si está en la lista, porque da error cuando los clientes escanean la red en busca de servers, pero no están en el juego aun. + print "Server Finish" + for jugador in ESPEJO.Tanques.values(): + # para informar a todos los jugadores sobre la desconexión de otro jugador + jugador.desconectados += "DES %s%s" % (ESPEJO.Tanques[self.client_address[0]].nombre, ESPEJO.TERMINATOR) + del ESPEJO.Tanques[self.client_address[0]] + #return SocketServer.BaseRequestHandler.finish(self) + return + + + +if __name__ == "__main__": + server = ThreadedTCPServer(("localhost", 5000), ThreadedTCPRequestHandler) + server.serve_forever() + + ''' + import SocketServer + class MyHandler(SocketServer.BaseRequestHandler): + def handle(self): + while 1: + dataReceived = self.request.recv(1024) + self.request.send(dataReceived) + myServer = SocketServer.ThreadingTCPServer(('',8881), MyHandler) + myServer.serve_forever( )''' |