Gente como puedo hacer para matar a los hilos socketudp y socketcp para que el programa se cierre solo y libere los recursos que esta utilizando. El programa es un cliente p2p que envía mensajes y transfiere archivos a otros clientes. Al arrancar el sistema hay que especificar el puerto por donde va a escuchar conexiones TCP y modificar la dirección de broadcast por la de su red para probarlo. Estoy estudiando socket. Saludos. José Codigo: import socket import threading import re import time import string import os from Queue import Queue
tamaniomensaje = 255 tamanioarchivo = 65535 class TCPSOCKET(threading.Thread): def __init__(self, puerto, cola): threading.Thread.__init__(self) self.puerto = puerto self.cola = cola def run(self): s = socket.socket() s.bind(("",self.puerto)) s.listen(5) #escuchamos solo a uno por vez archivo = False while True: salir = cola.get() if salir == True: s.close() print 'Fin de la historia TCP' break sc, direccion = s.accept() if archivo == False: #Fecha y hora actual hoy = "[%4d.%2.2d.%2.2d %2.2d:%2.2d] " %time.localtime()[:5] # se crea ulana conexion nueva por cada mensaje (para evitar problemas en esperas largas) try: mensaje = sc.recv(tamaniomensaje) except socket.timeout: print "Cerrado por inactividad" sys.exit() break mensajelista = mensaje.split(' ') mensaje = str(hoy + direccion[0]) + ' '+mensaje print mensaje #pasa el mensaje a una lista para poder analizarlo. if mensajelista[0] == '&file': archivo = True #ruta donde se va almacenar el archivo que va recibir( ruta = os.getcwd()+'/'+mensajelista[1] elif archivo == True: #Crea un archivo vacio para poder almacenar el contenido del archivo que va recivir. vacio = open(ruta, 'wb') #recibe el contenido. contenido = sc.recv(tamanioarchivo) #Escribe el contenido en el archivo vacio. vacio.write(contenido) #Cierra el archivo. vacio.close() #Establecemos la variale archivo a false. archivo = False sc.close() #se cierra la conexion class UDPSOCKET(threading.Thread): def __init__(self, puerto, cerrar): threading.Thread.__init__(self) self.socketdatagrama = '' self.puerto = puerto self.f = False self.ruta ='' self.cerrar = cerrar def run(self): espacio = ' ' msg = 'ON' while msg != 'OK': msg =self.cerrar.get() if msg == 'OK': print msg break else: hoy = "[%4d.%2.2d.%2.2d %2.2d:%2.2d] " %time.localtime()[:5] self.socketdatagrama = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.socketdatagrama.bind(('',self.puerto)) mensaje, cliente = self.socketdatagrama.recvfrom(1024) #pasamos el mensaje a una lista para poder analizarlo informacion = mensaje.split(espacio) #Analiza si se va recibir un archivo o un mensaje siplemente if informacion[0] == '&file' and len(informacion)>1: #Se utiliza para poder saber si se esta esperando un archivo. self.f = True #mostramos el mensaje mensaje = str(hoy + cliente[0]) + ' '+mensaje print mensaje #ruta donde se va almacenar el archivo que va recibir self.ruta = os.getcwd()+'/'+informacion[1] elif self.f == False: mensaje = str(hoy + cliente[0]) + ' '+mensaje print mensaje elif self.f == True: #creamos un archivo para poder almacenar el contenido que vamos a recibir. archivo = open(self.ruta, 'wb') archivo.write(mensaje) archivo.close() self.f = False self.socketdatagrama.close() #Funcion para enviar mensajes a un x destinatario, se crea un socket para poder enviar #enviar el mensaje y se cieera. def enviar_texto(ip,puerto,texto): try: s = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) s.connect((ip, puerto)) s.send(texto) s.close() return True except socket.error: return False #Funcion para enviar archivo a un x destinatario. #Se crea un socket, se envia el archivo y se cierra. def enviar_archivo(ip, puerto, ruta): #Abre el arachivo y lo almacena en un buffer para poder enviarcelo al destinatario. try: archivo = open(ruta, 'rb') paquete = archivo.read() archivo.close() #crea el socket para poder enviar el archivo. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #se conecta al receptor. s.connect((ip, puerto)) #Envia el archivo s.send(paquete) #Cierra el socket s.close except IOError: print 'Ruta incorrecta' #Valida la IP a la cual se desea enviar un mensaje, def ValidarIP(ip): pattern = r"\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b" if re.match(pattern, ip): return True else: return False #Funcion para realizar broadcast. #Se utiliza para poder enviar un mismo mensaje a todos los clientes. #Utilizamos un socket UDP def broadcast(puertoudp, mensaje): #Creamos el socket miSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) miSocket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) espacio = ' ' #pasa el mensaje a una lista para analizarlo. mensaje = mensaje.split(espacio) #Si el mensaje no contiene un archivo. if mensaje[0]!= '&file': #Transforma el mensaje a una cadena ya que esta en una lista. mensaje = espacio.join(mensaje) #Envia el mensaje a toda la red. miSocket.sendto(mensaje, ('10.168.1.255', puertoudp)) elif mensaje[0] == '&file' and len(mensaje)>1: #Al receptor solo le envia el nombre del archivo. ruta = mensaje[1] mensaje[1] = os.path.basename(ruta) #Pasa el mensaje a una cadena para poder enviarlo, el mensaje estaba contenido en una lista. mensaje = espacio.join(mensaje) try: #proceso para enviar el archivo. #abre ele archivo en modo lectura binaria archivo = open(ruta,'rb') #Alamcena el contenido del archivo mientra se lee en una variable para poder enviarlo. f = archivo.read() #Cierra el archivo. archivo.close() #Comunica a los receptores que va un archivo. miSocket.sendto(mensaje, ('10.168.1.255', puertoudp)) #Espera dos segundo para poder enviar el archivo, asi el receptor prepara todo para recibirlo. time.sleep(2) #Se envia el archivo. miSocket.sendto(f, ('10.168.1.255', puertoudp)) except IOError: print 'Ruta incorreta.' miSocket.close() miSocket.close() ######################################################################## puerto = int(raw_input('')) while puerto == 9999: print 'El puerto no puede ser 9999 ya que es el puerto de broadcast.' puerto = int(raw_input('')) salir = False cola = Queue() cerrar = Queue() cola.put(salir) cerrar.put('ON') socketcp = TCPSOCKET(puerto,cola); socketcp.start() socketudp = UDPSOCKET(9999,cerrar) socketudp.start() espacio = ' ' #Bucle que que recive los mensajes del operador. while True: #Pide al operador el mensaje. try: mensaje = raw_input('') except KeyboardInterrupt: salir = True fin = True cola.put(salir) #Mata el hilo socketudp cerrar.put('OK') break #Pasa el mensaje a lista para poder analizarlo. mensajelista = mensaje.split(espacio) #Optiene el primer elemento mensaje para averiguar si el mensaje esta destinado a un #unico receptor o a todos. IP = mensajelista[0] #Valida la IP if ValidarIP(IP): #Si el mensaje contiene un archivo if len(mensajelista) > 2 and mensajelista[1] == '&file': #Extrae la ruta de donde se encuentra ubicado el archivo. ruta = mensajelista[2] #De la ruta del archivo extrae el nombre del archivo, ya que es lo unico que le va enviar #al receptor para que no sepa en que directorio donde esta ubicado el archivo en la PC del emisor. mensajelista[2] = os.path.basename(mensajelista[2]) #Pasa mensaje de lista a cadena. smsenviar = espacio.join(mensajelista[1:]) #Envia el mensaje al destinatario if enviar_texto(IP,puerto,smsenviar): #Envia el archivo al destinatario. enviar_archivo(IP, puerto,ruta) else: print 'Error al conectarse al destinatario.' #Envia un mensaje en formato texto. else: smsenviar = espacio.join(mensajelista[1:]) if enviar_texto(IP, puerto,smsenviar ) == False: print 'Destinatario no conectado.' #si el mensaje tiene como destino a todos los clientes de la red del usuario. elif IP == '*': #Al mensaje le elimin el * y se lo pasa a la funcion broadcast para que se lo envie a toda la red. smsenviar = espacio.join(mensajelista[1:]) broadcast(9999, smsenviar) else: print 'Error al enviar el mensaje.'
import socket import threading import re import time import string import os from Queue import Queue tamaniomensaje = 255 tamanioarchivo = 65535 class TCPSOCKET(threading.Thread): def __init__(self, puerto, cola): threading.Thread.__init__(self) self.puerto = puerto self.cola = cola def run(self): s = socket.socket() s.bind(("",self.puerto)) s.listen(5) #escuchamos solo a uno por vez archivo = False while True: salir = cola.get() if salir == True: s.close() print 'Fin de la historia TCP' break sc, direccion = s.accept() if archivo == False: #Fecha y hora actual hoy = "[%4d.%2.2d.%2.2d %2.2d:%2.2d] " %time.localtime()[:5] # se crea ulana conexion nueva por cada mensaje (para evitar problemas en esperas largas) try: mensaje = sc.recv(tamaniomensaje) except socket.timeout: print "Cerrado por inactividad" sys.exit() break mensajelista = mensaje.split(' ') mensaje = str(hoy + direccion[0]) + ' '+mensaje print mensaje #pasa el mensaje a una lista para poder analizarlo. if mensajelista[0] == '&file': archivo = True #ruta donde se va almacenar el archivo que va recibir( ruta = os.getcwd()+'/'+mensajelista[1] elif archivo == True: #Crea un archivo vacio para poder almacenar el contenido del archivo que va recivir. vacio = open(ruta, 'wb') #recibe el contenido. contenido = sc.recv(tamanioarchivo) #Escribe el contenido en el archivo vacio. vacio.write(contenido) #Cierra el archivo. vacio.close() #Establecemos la variale archivo a false. archivo = False sc.close() #se cierra la conexion class UDPSOCKET(threading.Thread): def __init__(self, puerto, cerrar): threading.Thread.__init__(self) self.socketdatagrama = '' self.puerto = puerto self.f = False self.ruta ='' self.cerrar = cerrar def run(self): espacio = ' ' msg = 'ON' while msg != 'OK': msg =self.cerrar.get() if msg == 'OK': print msg break else: hoy = "[%4d.%2.2d.%2.2d %2.2d:%2.2d] " %time.localtime()[:5] self.socketdatagrama = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.socketdatagrama.bind(('',self.puerto)) mensaje, cliente = self.socketdatagrama.recvfrom(1024) #pasamos el mensaje a una lista para poder analizarlo informacion = mensaje.split(espacio) #Analiza si se va recibir un archivo o un mensaje siplemente if informacion[0] == '&file' and len(informacion)>1: #Se utiliza para poder saber si se esta esperando un archivo. self.f = True #mostramos el mensaje mensaje = str(hoy + cliente[0]) + ' '+mensaje print mensaje #ruta donde se va almacenar el archivo que va recibir self.ruta = os.getcwd()+'/'+informacion[1] elif self.f == False: mensaje = str(hoy + cliente[0]) + ' '+mensaje print mensaje elif self.f == True: #creamos un archivo para poder almacenar el contenido que vamos a recibir. archivo = open(self.ruta, 'wb') archivo.write(mensaje) archivo.close() self.f = False self.socketdatagrama.close() #Funcion para enviar mensajes a un x destinatario, se crea un socket para poder enviar #enviar el mensaje y se cieera. def enviar_texto(ip,puerto,texto): try: s = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) s.connect((ip, puerto)) s.send(texto) s.close() return True except socket.error: return False #Funcion para enviar archivo a un x destinatario. #Se crea un socket, se envia el archivo y se cierra. def enviar_archivo(ip, puerto, ruta): #Abre el arachivo y lo almacena en un buffer para poder enviarcelo al destinatario. try: archivo = open(ruta, 'rb') paquete = archivo.read() archivo.close() #crea el socket para poder enviar el archivo. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #se conecta al receptor. s.connect((ip, puerto)) #Envia el archivo s.send(paquete) #Cierra el socket s.close except IOError: print 'Ruta incorrecta' #Valida la IP a la cual se desea enviar un mensaje, def ValidarIP(ip): pattern = r"\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b" if re.match(pattern, ip): return True else: return False #Funcion para realizar broadcast. #Se utiliza para poder enviar un mismo mensaje a todos los clientes. #Utilizamos un socket UDP def broadcast(puertoudp, mensaje): #Creamos el socket miSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) miSocket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) espacio = ' ' #pasa el mensaje a una lista para analizarlo. mensaje = mensaje.split(espacio) #Si el mensaje no contiene un archivo. if mensaje[0]!= '&file': #Transforma el mensaje a una cadena ya que esta en una lista. mensaje = espacio.join(mensaje) #Envia el mensaje a toda la red. miSocket.sendto(mensaje, ('10.168.1.255', puertoudp)) elif mensaje[0] == '&file' and len(mensaje)>1: #Al receptor solo le envia el nombre del archivo. ruta = mensaje[1] mensaje[1] = os.path.basename(ruta) #Pasa el mensaje a una cadena para poder enviarlo, el mensaje estaba contenido en una lista. mensaje = espacio.join(mensaje) try: #proceso para enviar el archivo. #abre ele archivo en modo lectura binaria archivo = open(ruta,'rb') #Alamcena el contenido del archivo mientra se lee en una variable para poder enviarlo. f = archivo.read() #Cierra el archivo. archivo.close() #Comunica a los receptores que va un archivo. miSocket.sendto(mensaje, ('10.168.1.255', puertoudp)) #Espera dos segundo para poder enviar el archivo, asi el receptor prepara todo para recibirlo. time.sleep(2) #Se envia el archivo. miSocket.sendto(f, ('10.168.1.255', puertoudp)) except IOError: print 'Ruta incorreta.' miSocket.close() miSocket.close() ######################################################################## puerto = int(raw_input('')) while puerto == 9999: print 'El puerto no puede ser 9999 ya que es el puerto de broadcast.' puerto = int(raw_input('')) salir = False cola = Queue() cerrar = Queue() cola.put(salir) cerrar.put('ON') socketcp = TCPSOCKET(puerto,cola); socketcp.start() socketudp = UDPSOCKET(9999,cerrar) socketudp.start() espacio = ' ' #Bucle que que recive los mensajes del operador. while True: #Pide al operador el mensaje. try: mensaje = raw_input('') except KeyboardInterrupt: salir = True fin = True cola.put(salir) #Mata el hilo socketudp cerrar.put('OK') break #Pasa el mensaje a lista para poder analizarlo. mensajelista = mensaje.split(espacio) #Optiene el primer elemento mensaje para averiguar si el mensaje esta destinado a un #unico receptor o a todos. IP = mensajelista[0] #Valida la IP if ValidarIP(IP): #Si el mensaje contiene un archivo if len(mensajelista) > 2 and mensajelista[1] == '&file': #Extrae la ruta de donde se encuentra ubicado el archivo. ruta = mensajelista[2] #De la ruta del archivo extrae el nombre del archivo, ya que es lo unico que le va enviar #al receptor para que no sepa en que directorio donde esta ubicado el archivo en la PC del emisor. mensajelista[2] = os.path.basename(mensajelista[2]) #Pasa mensaje de lista a cadena. smsenviar = espacio.join(mensajelista[1:]) #Envia el mensaje al destinatario if enviar_texto(IP,puerto,smsenviar): #Envia el archivo al destinatario. enviar_archivo(IP, puerto,ruta) else: print 'Error al conectarse al destinatario.' #Envia un mensaje en formato texto. else: smsenviar = espacio.join(mensajelista[1:]) if enviar_texto(IP, puerto,smsenviar ) == False: print 'Destinatario no conectado.' #si el mensaje tiene como destino a todos los clientes de la red del usuario. elif IP == '*': #Al mensaje le elimin el * y se lo pasa a la funcion broadcast para que se lo envie a toda la red. smsenviar = espacio.join(mensajelista[1:]) broadcast(9999, smsenviar) else: print 'Error al enviar el mensaje.'
_______________________________________________ Python-es mailing list Python-es@python.org http://mail.python.org/mailman/listinfo/python-es FAQ: http://python-es-faq.wikidot.com/