1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
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( )'''
|