#!/usr/bin/env python # -*- coding: utf-8 -*- # TCP_Server_thread_Stream.py por: # Flavio Danesse # 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( )'''