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/

Responder a