Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/TCP_Server_thread_Stream.py
diff options
context:
space:
mode:
Diffstat (limited to 'TCP_Server_thread_Stream.py')
-rw-r--r--TCP_Server_thread_Stream.py234
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( )'''