labpyproject.core.net.custom_TCP

Prototype de framework client/serveur visant à résoudre les questions soulevées dans l’article : https://docs.python.org/3/howto/sockets.html

Protocole(s) supporté(s) : TCP

Principes :

  • toute requète est découpée (au besoin) en blocs de taille CustomRequestHelper.BUFFERSIZE

  • une « couche de protocole » identifie chaque bloc avec :

    • un prefix de bloc : CustomRequestHelper.BLOC_PREFIX (“”<#bp#>””)

    • un entête : |n° bloc/nombre de blocs|uid|nombre de caractères du message|

    • la portion de message du bloc

    • un suffixe de bloc : CustomRequestHelper.BLOC_SUFFIX (“”<#bs#>””)

  • des codes (et arguments) de commande permettent de gérer : les accusés de réception (permettant de « garantir » la réception d’un message), l’identification unique d’un client (uid), la communication de son adresse de réception (pour garantir le canal serveur vers client, cf limites de ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer))

Exemple

Blocs binaires échangés lors de la séquence de connection.

1- Envoi d’une demande d’uid par le client :

b”<#bp#>|1/1|None|18|[cmd:ASK_FOR_UID|]<#bs#>”

2- Réception du bloc par le Serveur, qui retourne l’identifiant uid0 au client :

b”<#bp#>|1/1|gen_svr_id|4|uid0<#bs#>”

3- Réception du bloc par le client, qui retourne ses infos de connection :

b”<#bp#>|1/1|uid0|56|[cmd:SET_CLIENT_READ_INFOS|host=192.168.0.7&port=11548]<#bs#>”

4- Réception du bloc par le serveur qui retourne un accusé de réception :

b”<#bp#>|1/1|gen_svr_id|26|[cmd:CONFIRM_RECEPTION|]56<#bs#>”

5- Réception de la confirmation par le client avec le bon nombre de caractères (56).

La communication bilatérale est alors établie.

Autres fonctionnalités :

  • possibilité de déconnecter / reconnecter les composants « à chaud ».

  • détection des « déconnections sauvages » distantes pour limiter le nombre de reconnection et renvois.

  • informe l’application associée (BUSINESSComp) de l’état des différentes connections et des erreurs d’envoi.

À faire

Evolutions souhaitables:

  • supporter plusieurs codes, regrouper codes et msguid en entête

  • paralléliser les envois de requètes côté serveur (voir méthode send du serveur frontal)

  • à décliner pour les trois autres protocoles supportés par socketserver?

Application concrète

Dans le jeu labpyrinthe :

AppManager (voir labpyproject.apps.labpyrinthe.app.application, dans la méthode privée _init_network) crée automatiquement un composant réseau (CustomTCPServerContainer ou CustomTCPThreadedClient), si l’application est de type serveur (AppManager.APP_SERVER) ou respectivement client (AppManager.APP_CLIENT).

Classes

CustomTCPServerContainer(server_address[, …])

Serveur « frontal » (conteneur du ThreadedTCPServer).

ThreadedTCPServer(server_address, …[, …])

Serveur TCP prenant en charge chaque requète dans un thread, lui même géré dans un thread par son conteneur CustomTCPServerContainer.

CustomTCPRequestHandler(request, …)

Objet instancié pour chaque requète entrante (gérée dans un thread par ThreadedTCPServer).

ParseDataError(message)

Exception associée à une erreur de parsing de donnée

CustomRequestHelper

Utilitaire statique proposant des services :

CustomTCPThreadedClient(server_address[, …])

Objet client du serveur CustomTCPServerContainer

Class Inheritance Diagram

Inheritance diagram of labpyproject.core.net.custom_TCP.CustomTCPServerContainer, labpyproject.core.net.custom_TCP.ThreadedTCPServer, labpyproject.core.net.custom_TCP.CustomTCPRequestHandler, labpyproject.core.net.custom_TCP.ParseDataError, labpyproject.core.net.custom_TCP.CustomRequestHelper, labpyproject.core.net.custom_TCP.CustomTCPThreadedClient