Está en la página 1de 13

GPS Network Socket

David Pineda Osorio

11 de junio de 2019

Índice
1. Versión de Documentación 2

2. Introducción 2

3. ¿Cómo instalar? 3
3.1. Con pip desde PyPi . . . . . . . . . . . . . . . . . . . . . . . 4

4. Las Dependencias 4
4.1. De la biblioteca estándar . . . . . . . . . . . . . . . . . . . . . 4
4.2. Creadas por DP . . . . . . . . . . . . . . . . . . . . . . . . . . 5
4.2.1. Networktools . . . . . . . . . . . . . . . . . . . . . . . 5

5. Settings 5

6. La Clase Principal 6
6.1. queue_status . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
6.2. set_ssl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
6.3. set_logger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
6.4. set_server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
6.5. set_client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
6.6. get_writer, get_reader . . . . . . . . . . . . . . . . . . . . . . 6
6.7. generate_msg . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
6.8. gen_idx . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
6.9. send_msg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
6.10. recv_msg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
6.11. set_reader_writer . . . . . . . . . . . . . . . . . . . . . . . . 7
6.12. connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
6.13. clean_socket . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

1
6.14. create_server . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
6.15. create_client . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
6.16. __enter__ y exit . . . . . . . . . . . . . . . . . . . . . . . . 8

7. Las Clases Asociadas 8


7.1. GNSocketBase (socket_base.py) . . . . . . . . . . . . . . . . 10
7.1.1. Corrutinas . . . . . . . . . . . . . . . . . . . . . . . . . 10
7.2. GNSocketServer (socket_server.py) . . . . . . . . . . . . . . . 11
7.3. GNSocketClient (socket_client.py) . . . . . . . . . . . . . . . 11

8. Ejemplos y pruebas 11
8.1. Habilitar un server y client sencillos . . . . . . . . . . . . . . . 11
8.2. En la carpeta advance . . . . . . . . . . . . . . . . . . . . . . 12
8.3. En la carpeta advance_ssl . . . . . . . . . . . . . . . . . . . . 12
8.4. En la carpeta advance_uv . . . . . . . . . . . . . . . . . . . . 12
8.5. En la carpeta advance_uv_ssl . . . . . . . . . . . . . . . . . 12
8.6. Carpeta advance_uv_class . . . . . . . . . . . . . . . . . . . 12

1. Versión de Documentación
0.9.2

2. Introducción
Este modulo está hecho para habilitar la comunicación mediante el sis-
tema socket (ver documentación),que simulan un camino entre dos puntos,
habilitando un canal para la intercomunicación de datos.
En el lenguaje Python se tiene habilitado el módulo socket y con el
módulo asyncio es posible establecer comunicaciones asíncronas entre las
partes.
Según el tipo de socket (entre los principales)

UNIX define un espacio de intercomunicación dentro del mismo compu-


tador
TCP define un espacio de intercomunicación dentro de la red IP.

Se habilita, dadas las condiciones, este canal de comunicación.


Lo único que comunica socket de un punto a otro es información en
bytes, esto es muy importante, ya que cualquier elemento de información u
objeto debe ser transformado a una cadena de bytes, es decir serializado.

2
Dependiendo de la capacidad de canal del canal socket, se debe sec-
cionar el objeto serializado de manera secuencial y enviar.
Existen dos elementos importantes en una comunicación socket.
servidor es quien escucha y atiende diferentes clientes, fuente de datos o
acciones.
cliente es cada instancia de comunicación que recibe información del servi-
dor.
Una conexión socket, al establecer un canal. Habilita una línea en una
dirección A :: servidor ->cliente y otra línea en el otro sentido B :: cliente
->servidor. Los mensajes se intercambian, desde servidor a cliente, por A
y, desde cliente a servidor, por B.
Esta forma de comunicar permite la creación de objetos abstractos, se-
gún Python, StreamReader y StreamWriter (reader, writer). Que tienen la
función específica, cada uno, de leer las cadenas de bytes y de escribir o
enviar.
Ahora bien, necesitamos crear una funcionalidad que nos permita es-
tar constantemente enviando o recibiendo información de manera asíncrona.
Para eso será necesario utilizar las técnicas desarrolladas en el módulo task-
tools, que establecen el modo de definir tareas cíclicas e independientes con
corrutinas.
Con esto se habilita todo el potencial de comunicación entre sistemas o
procesos. Ya que mediante el uso de los objetos queue de python es posible
modelar sistemas modulares que se comuniquen a través de socket.
Siendo así una forma estándar sobre la cual se hace posible definir proto-
colos de comunicación, o formas de estructurar los contenidos de un mensaje.
A manera general se ha escogido, para facilitar las comunicaciones, un proto-
colo que intercambie diccionarios python u objetos json o maps, es decir
objetos serie que se definen en base al par (llave, valor).
Además, es necesario considerar fundamental comprender el funciona-
miento de este sistema ya que es la base de sistemas de comunicación algo
más complejos como DBUS, que facilitan ciertas situaciones para el inter-
cambio de mensajes.

3. ¿Cómo instalar?
Primero, deberás establecer un ambiente virtual con Python 3.5 o, de
preferencia, Python 3.7, que permite usar las clases ya definidas modulares.
Luego, el módulo se puede clonar desde el repositorio gitlab.

3
# Clonar estos proyectos
git clone https://gitlab.com/pineiden/gus
git clone https://gitlab.com/pineiden/tasktools
git clone https://gitlab.com/pineiden/networktools

Para, por último, proceder a instalar dependencias y el mismo módulo


(en ambiente virtual)

# quitando los modulos que vienen de gitlab


grep -v "git" requeriments.txt|xargs pip install

Ahora, instalando los módulos clonados, de manera siguiente, en cada


carpeta una instalación en modo desarrollo (mientras tanto).

python setup.py develop

3.1. Con pip desde PyPi


Se instala (no la versión de desarrollo) sino aquella publicada en la pla-
taforma https://pypi.org.

pip install networktools


pip install tasktools
pip install gnsocket

4. Las Dependencias
4.1. De la biblioteca estándar
os

Es el módulo que nos permite acceder a recursos del sistema, como va-
riables de ambiente, entre otras.

socket

Es el módulo base para activar la comunicación socket, se basa en la


implementación de C

asyncio

Es el módulo que permite activar las corrutinas, la comunicación asín-


crona y todos los recursos que utilizan (async, await)

4
errno

Es una colección de errores o excepciones estándar en python.

math

Habilita operaciones matemáticas fundamentales.

re

Habilita el uso de expresiones regulares.

loggin

Permite realizar el registro de acciones, errores y fallas en un archivo.

ssl

Permite y habilita la encriptación de las comunicaciones de manera se-


gura

path

Permite el uso de rutas o directorios.

4.2. Creadas por DP


4.2.1. Networktools
library una serie de funciones para la generación y tratamiento de strings,
facilitando la operación de ciertas acciones rutinarias.

colorprint es una serie de funciones que imprimen en la terminal en colores,


muy útil para diferenciar y debuggear.

5. Settings
En este caso se define un archivo "./conf/socket_conf.py* que contiene
los parámetros principales que definen tanto el tipo de socket escogido, como
valores por defecto que definen el canal de comunicación y elementos para
la prueba de comunicación.
Este archivo, en cada instalación debe ser copiado del .py.bk a .py y
ajustado a las necesidades particulares.

5
6. La Clase Principal
Por asociación, debido a que el software general está dedicado a la comu-
nicación de sistemas para geodesia en CSN, es que le he puesto el prefijo
GN o GNC a algunas clases de este módulo.
La clase principa, GNSocket. permite activar un objeto socket server
o cliente asociado a una dirección por el par (host, port) o bien una ruta
a un archivo socket (caso Unix). Además, los parámetros de redefinición
opcionales que se pueden ingresar mediante el diccionario kwargs.

6.1. queue_status
Es cuando asociamos una cola por la cual compartir los estados del avance
de la conexión. Se puede usar para conectar con interfaces y mostrar la
evolución de la conexión.

6.2. set_ssl
Permite establecer la comunicación con seguridad, definir los certificados,
etc.

6.3. set_logger
Es una función que define todos los parámetros y objetos para mantener
operando el log.

6.4. set_server
Función que permite definir los parámetros de servidor. Dirección o ruta
según el caso.

6.5. set_client
Función que permite definir los parámetros de cliente. Dirección o ruta
según el caso.

6.6. get_writer, get_reader


Funciones que permiten obtener los objetos Writer o Reader de la ins-
tancia o conexión.

6
6.7. generate_msg
Esta función generadora, dado el uso de yield, necesita que se le en-
tregue un string. Se encarga de serializar y seccionar para el envío adecuado
mediante el canal.

6.8. gen_idx
Genera un id aleatorio.

6.9. send_msg
Es la función asíncrona elemental para enviar un mensaje, lo encapsula
a otra función asíncrona que llama a generate_msg.

6.10. recv_msg
Es la función análoga a send_msg, pero está preparada para recibir todo
el mensaje, volver a encapsularlo y de-serializar.

6.11. set_reader_writer
Permite asociar a un identificador idc con el canal definido por el par
(reader, writer).

6.12. connect
Es la corrutina o función asíncrona que cada cliente necesita activar
para realizar la conexión. Realiza intentos hasta que el status cambia. Ade-
más aquí se puede observar como es que se realiza una conexión asociando
un objeto socket con el comportamiento asyncio.

6.13. clean_socket
Es la función para limpiar posibles conexión realizadas al mismo puerto
(Socket TCP)

6.14. create_server
Es la corrutina o función asíncrona que permite activar la disponibi-
lidad del servidor para escuchar las llamadas a conexión de cada cliente.

7
Una vez que está disponible, se establece que cada cliente acciona una
función callback_io que gestiona la actividad de los Stream de canal:
StreamReader y StreamWriter, todo esto asociados mediante un identi-
ficador único.

6.15. create_client
De manera análoga, cada cliente debe activar la conexión mediante su
propio par (reader, writer). A partir de aquí, es posible comunicar dos puntos
e inter-operar mediante mensajes.

6.16. __enter__ y exit


Son los métodos mágicos que permiten activar la clase mediante estruc-
turas de contexto (with, as).

7. Las Clases Asociadas


Una vez que ya tenemos definida la clase fundamental GNSocket, se
hace posible establecer un esquema modular de objetos Servidor y Cliente
que se comuniquen entre sí y, con otros procesos, comunicarse mediante colas
queue.
Entonces, la idea es que entregando solamente dos colas (una para co-
municar desde el proceso al objeto socket, otra para comunicar del socket al
proceso) y la dirección del otro punto, sea posible comunicar e interoperar.
De manera más gráfica, en la figura.

8
9
Utilizando además los métodos disponibles, de contexto y de activación
asíncrona, es posible tener las siguientes clases disponibles.

7.1. GNSocketBase (socket_base.py)


Es una clase que no se usa directamente, sino que se debe implementar
mediante herencia en otra clase (aquella que define el modo de comunicación
(cliente o servidor)). Esta clase define el protocolo :: el objeto o estructura
del mensaje.
Requiere que le entreguemos el par de colas de comunicación, terminal
es el proceso particular.

queue_n2t cola de comunicación red->terminal

queue_t2n cola de comunicación terminal->red

El modo de operación

server para servidor

client para cliente

La dirección en el diccionario kwargs.

address por defecto (localhost, 6666)

Función que gestiona las excepciones, bajo la llave.

callback_exception una función que gestione las excepciones

7.1.1. Corrutinas
El par de corrutinas definidas establecen el modo en como leen las colas
desde un proceso (desconocido para socket) pero que recibe mensajes con la
estructura de diccionarios.

sock_write es la corrutina que escribe o envía el mensaje al otro punto

sock_read es la corrutina que recibe los mensajes desde el otro punto

10
7.2. GNSocketServer (socket_server.py)
Es la clase que permite activar un servidor socket, asociado a las colas
(n2t,t2n), las opciones que se heredes por kwargs.
Solamente define una función clásica, que es la que activa la tarea de
establecer un objeto gnsocket en contexto.
Este objeto en contexto activa la corrutina callback_io llamada, en esta
ocasión socket_io, con argumentos los objetos (reader, writer).
La corrutina socket_io es una función que activa dos tareas indepen-
dientes y cíclicas. Una para leer y otra para escribir. Con esto es posible
establecer activamente un canal de comunicación con otro punto específico,
determinado por el identificador idc

7.3. GNSocketClient (socket_client.py)


Es la clase que permite activar un cliente socket, asociado a las colas
(n2t, t2n), incluyendo las opciones que se hereden por kwargs.
Solamente se define una función clásica en que se activa la tarea para
establecer un objeto gnsocket en contexto.
Luego, dentro de la función y el contexto, se define una corrutina soc-
ket_io que establece las tareas cíclicas e independientes de los métodos
heredados (sock_write, sock_read)
Esta corrutina es una función del tipo callback_io que se activa al
generar una conexión cliente socket.

8. Ejemplos y pruebas
Los siguientes ejemplos y pruebas están alojados en la carpeta ./test
En general, para realizar las pruebas es necesario que utilices dos termi-
nales. En una activar el servidor y en otra activar el cliente.

8.1. Habilitar un server y client sencillos


Inmediatamente dentro de la carpeta hay un archivo server.py, que
habilita un socket server y escucha algunos mensajes.

python server.py

En otra terminal

python client.py

11
Veremos que si todo va bien, el cliente recibe el mensaje de prueba oficial
y también el mensaje de bienvenida.
También, desde el cliente podrás enviar mensajes de texto hasta el otro
lado, ¡genial!

8.2. En la carpeta advance


En esta carpeta, de manera similar con dos terminales, ejecutamos server
y client.
¿Qué diferencia hay con la anterior?
Está un poquito más ordenada. Nos permite identificar de manera más
clara el par (reader, writer) por cliente.
De manera análoga al caso anterior, cliente recibe el mensaje de prueba
y bienvenida, además que permite enviar mensajes.

8.3. En la carpeta advance_ssl


Es prácticamente el mismo esquema, en que se le añade una capa de
seguridad controlada por ssl.
Contiene, además, un script que permite generar los certificados de ma-
nera sencilla, ejecutándolo. (Tal vez no sea el certificado más seguro, hay que
investigar). Pero, a modo de ejemplo, permite mostrarnos como establecer
comunicaciones encriptadas a través de socket.
Al iniciar el objeto, se asocia al archivo de certificados creado.

8.4. En la carpeta advance_uv


En este caso, lo único que cambia es la selección de event loop de
asyncio, en que se utiliza una implementación llamada uvloop

8.5. En la carpeta advance_uv_ssl


En este caso, lo único que cambia es la selección de event loop de asyn-
cio, en que se utiliza una implementación llamada uvloop pero añadiendo
la capa de seguridad ssl

8.6. Carpeta advance_uv_class


Se implementa el uso de las clases GNSocketServer y GNSocket-
Cliente en conjunto con una clase Operacion que habilita o reconoce un
par de comandos recibidos como mensaje desde el cliente.

12
En el cliente se tiene la implementación con interfaz gráfica (Qt-PySide2),
que permite seleccionar dos acciones {sumar, multiplicar} y enviar dos
valores. Luego de calculados en servidor, se muestra el resultado. El archivo
se llama gui_client.pt.

13

También podría gustarte