¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Python 3
  3. Programación asíncrona: avanzada
Extrait - Python 3 Tratamiento de los datos y técnicas de programación
Extractos del libro
Python 3 Tratamiento de los datos y técnicas de programación
1 opinión
Volver a la página de compra del libro

Programación asíncrona: avanzada

Transportes y protocolos

1. Introducción

Estas nociones de transporte y de protocolo (y podríamos añadir la noción de flujo), son nociones de bajo nivel. Estas nociones se hacen para permitir automatizar las implementaciones de alto rendimiento, de casos prácticos asíncronos usuales, como veremos más adelante para del TCP, la UDP o las llamadas a procesos externos.

Los objetos Transport o Protocol no se hicieron para crearse y gestionarse directamente en scripts o aplicaciones, sino que se diseñaron como herramientas de destino de librerías que proporcionan herramientas de alto nivel, como por ejemplo autobahn, que se presenta en el capítulo sobre la programación de red.

Vamos a intentar presentar aquí los conceptos generales, sabiendo que la parte en la que insistiremos más, será la que presenta los transportes y protocolos ya implementados por el lenguaje.

Los transportes se hacen para describir la manera en la que los datos se transmiten. Desde el momento en que se habla de transmisión de datos de bajo nivel, se habla de bytes. Por lo tanto, los transportes describen cómo transportar los bytes.

Los protocolos se hacen para describir cuáles son los datos a transmitir, en qué orden y cuando. En general, implementan los RFC (especificaciones genéricas) y por lo tanto, pueden ser potencialmente muy complejos. Cada instancia de un transporte se asocia a una y solo una instancia de protocolo.

2. Transportes

Los transportes son clases proporcionadas por asyncio, que permiten crear una abstracción de un canal de comunicación. Generalmente usted no instancia los transportes, sino que lo hace el bucle de eventos. Este último va a iniciar el transporte y después el canal de comunicación subyacente.

Un transporte sirve para utilizarse por un protocolo y a este respeto, siempre se asocia una instancia de transporte a una instancia de protocolo, los dos trabajan juntos.

Para empezar, vamos a importar la clase de base:

>>> from asyncio import BaseTransport 

Para crear un transporte, debe heredar de esta clase e implementar cuatro métodos, que son is_closing, close, set_protocol y get_protocol. Para resolver estos cuatro métodos, vamos simplemente a utilizar dos atributos privados _is_closing y _protocol. Estos últimos se inicializan en el constructor.

Para...

Flujo

1. Introducción

Los flujos son una herramienta de más bajo nivel que los protocolos y los transportes, que hemos presentado anteriormente. Permiten manipular directamente los datos intercambiados. Un flujo es unidireccional y puede ser en modo lectura o escritura. Para tener el equivalente de un transporte entre, por ejemplo, un cliente y un servidor, hay que poner en marcha un flujo que sea en modo lectura para el cliente y en modo escritura para el servidor, así como otro flujo que sea en modo escritura para el cliente y en modo lectura para el servidor.

Se aconseja utilizar preferiblemente los protocolos, pero en algunos casos, el uso de un sencillo flujo puede resultar útil. Por lo tanto, vamos a presentar la manera de utilizarlos. 

2. Ejemplo con el protocolo TCP

Aquí vamos a escribir un nuevo servidor TCP, que devuelve lo que recibe, pero usando los flujos. A continuación se muestra la función que realiza este trabajo:

async def echo(reader, writer):  
    address = writer.get_extra_info("peername")  
    logger = logging.getLogger(f"Client {address}")  
    coloredlogs.install(fmt="%(name)s: %(message)s", level="DEBUG", 
logger=logger)  
    logger.debug("connection made {address}")  
  
    while True:  
        data = await reader.read(128)  
        if data:  
            logger.debug(f"received {data!r}")  
           ...