El módulo estándar asyncore
provee una simple interfaz para escribir servidores y clientes que trabajen de manera sincrónica. De este modo, un servidor puede albergar gran cantidad de clientes y responder a cada uno de ellos al mismo tiempo.
Código de fuente de un cliente y un servidor que constituyen a una sala de chat, en donde los clientes reciben los mensajes en tiempo real. Para cerrar la conexión, tipear «salir» (sin comillas).
Descargar código de fuente: asyncorechat.zip
client.py
#!/usr/bin/env python # -*- coding: utf-8 -*- # # client.py # # Copyright 2013 Recursos Python - www.recursospython.com # # import asyncore from socket import AF_INET, SOCK_STREAM from threading import Thread class TCPClient(asyncore.dispatcher_with_send): def __init__(self, host=("localhost", 6000)): asyncore.dispatcher_with_send.__init__(self) self.create_socket(AF_INET, SOCK_STREAM) self.connect(host) Thread(target=self.sender).start() # Nuevo hilo def sender(self): # Enviar los mensajes desde un hilo aparte, # para que en paralelo se sigan reciban los # mensajes del servidor. while True: data = raw_input("\n") if data: if data.lower() == "salir": break else: self.sendall(data) else: print "Debes escribir un mensaje." self.handle_close() def handle_connect(self): print "Has entrado al chat." def handle_close(self): print "Has salido del chat." self.close() def handle_read(self): """Imprimir los mensajes""" print self.recv(1024) if __name__ == "__main__": client = TCPClient() asyncore.loop()
server.py
#!/usr/bin/env python # -*- coding: utf-8 -*- # # server.py # # Copyright 2013 Recursos Python - www.recursospython.com # # import asyncore from socket import AF_INET, SOCK_STREAM # Diccionario para cada uno de los clientes. # No es lo más recomendado usar variables globales. clients = {} class TCPHandler(asyncore.dispatcher_with_send): def __init__(self, conn): asyncore.dispatcher_with_send.__init__(self, conn) self.addr = "%s:%d" % self.addr def handle_read(self): """Enviar el mensaje recibido a cada uno de los clientes""" data = self.recv(1024) if data: for client in clients: clients[client].send("%s dice: %s" % (self.addr, data)) def handle_close(self): print self.addr + " se ha desconectado." del clients[self.addr] self.close() class TCPServer(asyncore.dispatcher): def __init__(self, port): asyncore.dispatcher.__init__(self) self.create_socket(AF_INET, SOCK_STREAM) self.set_reuse_addr() self.bind(("localhost", port)) self.listen(20) def handle_accept(self): client = self.accept() if client is not None: conn, addr = client handler = TCPHandler(conn) clients[handler.addr] = handler print handler.addr + " se ha conectado." if __name__ == "__main__": server = TCPServer(6000) asyncore.loop()
Curso online 👨💻
¡Ya lanzamos el curso oficial de Recursos Python en Udemy!
Un curso moderno para aprender Python desde cero con programación orientada a objetos, SQL y tkinter
en 2024.
Consultoría 💡
Ofrecemos servicios profesionales de desarrollo y capacitación en Python a personas y empresas. Consultanos por tu proyecto.
larson says:
solo en la version 2 de python funciona bien ya en la 3 da un error tras otro