11.18 asyncore -- Gestor de socket asíncrono

Este módulo proporciona la infraestructura básica para escribir clientes y servidores de servicios de socket asíncrono.

Hay dos formas de hacer que un programa en un único procesador haga ``más de una cosa a la vez.'' La programación multi-hilo o multi-hebra es la forma más simple y usual de hacerlo, pero hay otra técnica muy distinta, que tiene casi todas las ventajas de la multi-hebra, sin usar múltiples hilos de ejecución. Sólo es verdaderamente práctica si el programa depende en gran medida de los puertos de entrada/salida. Si el programa depende de la CPU, entonces las hebras de ejecución prioritaria son probablemente la mejor elección. No obstante, los servidores de red raramente dependen de la CPU.

Si el sistema operativo permite la llamada al sistema select() en su biblioteca de E/S (casi todos lo hacen), es posible emplearla para simular múltiples canales de comunicación a la vez, pudiendo realizar otra tarea mientras la comunicación E/S se produce en ``segundo plano''. Aunque esta estrategia puede parecer extraña y complicada, especialmente al principio, es en muchos aspectos mucho más fácil de enterder y controlar que la programación con múltiples hebras. El módulo descrito aquí resuelve muchos de los problemas más complejos, simplificando la tarea de construir sofisticados clientes y servidores de red de alto rendimiento.

dispatcher ()
Se trata de una ligera envoltura alrededor de un objeto socket de bajo nivel. Para hacerlo más útil, tiene unos pocos métodos que gestionan sus eventos. Por otra parte, puede ser tratado como un objeto socket sin bloqueos. La interfaz directa entre el bucle de selección y el objeto socket la componen los métodos handle_read_event() y handle_write_event(). Son llamados cada vez que un objeto desencadena ese evento.

El desencadenante de esos eventos de bajo nivel puede indicar si ciertos eventos de más alto nivel han ocurrido, depediendo del tiempo y el estado de la conexión. Por ejemplo, si se ha indicado a un socket que se conecte a otra máquina, se puede saber que la conexión se ha establecido cuando el socket dispara un evento de escritura (en ese momento se puede escribir en él con certeza de éxito). Los eventos implícitos de más alto nivel son:

Event  Description 
handle_connect() Provocado por un evento de escritura
handle_close() Provocado por un evento de lectura sin datos disponibles
handle_accept() Provocado por un evento de lectura en un socket de escucha

Este conjunto de eventos en el nivel de usuario es mayor que el de los básicos. La lista completa de métodos que pueden ignorarse en las subclasificaciones son:

handle_read ()
Se llama cuando hay nuevos datos para leer en un socket.

handle_write ()
Se llama cuando hay un intento de escribir datos en el objeto. Normalmente en este método se crea el `buffer' necesario para mejorar el rendimiento. Por ejemplo:

def handle_write(self):
    sent = self.send(self.buffer)
    self.buffer = self.buffer[sent:]

handle_expt ()
Se llama cuando hay datos fuera de banda (`out of band' - OOB) en la conexión de un socket. Esto no ocurre casi nunca, ya que los datos OOB se usan raramente y su soporte es escaso.

handle_connect ()
Se llama cuando el socket realiza la conexión. Se suele usar para enviar un mensaje de bienvenida o algo similar.

handle_close ()
Se llama cuando el socket se cierra.

handle_accept ()
Se llama en los sockets de escucha cuando aceptan una nueva conexión.

readable ()
En cada paso por el bucle select() se examina el conjunto de sockets y se llama a este método para ver si es necesaria una lectura. Por defecto el método devuelve 1, indicando que -por defecto- todos los canales will be interested.

writeable ()
Cada vez que a través del bucle select()se examina el conjunto de sockets, se llama a este método para comprobar si es necesaria una operación de escritura. Por defecto el método devuelve 1, indicando que -por defecto- todos los canales will be interested.

Además existen métodos básicos, necesarios para construir y manipular ``canales'', que son en este contexto las conexiones del socket. La mayoría de ellos son prácticamente idénticos a los métodos de socket.

create_socket (family, type)
Igual que la creación de un socket normal; usa las mismas opciones. Véase la documentación del módulo socket para una mayor información sobre creación de sockets.

connect (address)
Como con el objeto socket normal, address es una tupla, siendo su primer elemento la máquina ``anfitrión'' (``host'') a la que se dirige la conexión, y el segundo el puerto.

send (data)
Envía data a través del socket.

recv (buffer_size)
Lee al menos buffer_size bytes del socket.

listen ([backlog])
Modo de escucha o espera de conexiones al socket. El argumento backlog especifica el número máximo de conexiones en cola, que deben ser al menos 1; el valor máximo depende del sistema (normalmente 5).

bind (address)
Enlaza el socket a address. El socket no debe estar ya enlazado. (El formato de address depende de la familia de direcciones -ver más arriba-).

accept ()
Acepta una conexión. El socket ha de estar enlazado a una dirección y en modo de escucha. El valor de retorno es (conn, address) donde conn es un nuevo objeto socket que se puede emplear para enviar y recibir datos a través de la conexión, y address es la dirección asignada al socket en el otro extremo de la conexión.

close ()
Cierra el socket. Todas las operaciones posteriores sobre el socket fallarán. El otro extremo no recibirá más datos (después de enviar los datos en cola). Los sockets son automaticamente cerrados tras la operación de ``recogida de basura''.


Subsections

Ver Sobre este documento... para obtener información sobre sugerencias.