Bonsoir,
J'ouvre un nouveau topic pour vous posez quelques questions sur le C++ et la modélisation d'un projet. Mon projet est déjà bien avancé bien que je rencontre encore des difficultés. Ayant un certains laps de temps encore, j'aimerais pouvoir améliorer considérablement ce que j'ai fait. Ce topic fait suite à un topic que j'avais ouvert sur progdupeu.pl où Freedom m'avait très gentillement répondu : Modéliser les TLV.
Ayant peu d'expérience en programmation, j'aimerais améliorer ma technique aussi bien en C++ que de façon général pour avoir des programmes un peu plus safe.
Mon objectif premier est d'utiliser un maximum des idiomes du C++ afin d'éviter les écueils du C tout en restant à mon avis. Je souhaitais aussi utiliser un maximum les fonctionnalités de C++ 11 (voir 14) afin d'avoir un code moderne.
Si je vous dis tout ça, c'est notamment pour vous guider dans les réponses à mes futures questions
Présentation générale
Le but du projet est d'implémenter un protocole réseaux décentralisée qui permet l'échange de données. L'objectif étant que tous le monde reçoit les données de tous le monde. Le protocole s'articule autour de paquet qui sont composés de Tlv. Un Tlv encapsule de l'information à communiquer à un pair. Pour plus d'informations sur le projet, je peux vous l'envoyer en privé.
Question 1
Ma première question concerne les types. Ayant goûté aux joies de la programmation fonctionnelle avec Ocaml ou Haskell, avoir un typage fort est extrêmement intéressant. J'ai donc essayé d'utiliser au mieux les types fournit par la librairie standard. Cependant, durant l'implémentation du projet, je me suis rendu compte que j'avais de nombreux cast à faire à cause des données qui transitaient à travers le réseaux.
Par exemple, si je souhaitais stocker une donnée sur un octet, j'utilisais le type uint8_t que je devrais caster plus tard en unsigned char. Ou bien un uint64_t que je devrais caster ensuite en unsigned char[8] .
Donc après coup, je me demande si les types uint8_t sont vraiment utile. Mon idée, c'était quand on voit ça, on se dit très bien ça va être un entier sur un octet. Alors qu'un unsigned char c'est peut-être moins évident ?
D'autre part, je manipule aussi des données binaires de longueur variable. En me renseignant, j'utilisais un basic_string<unsigned char> , est-ce le bon type à utiliser ?
Question 2
L'échange de données avec d'autres pairs ne se fait pas forcément de façon synchrone. En particulier, je souhaiterais pouvoir envoyer des données quand un timeout se déclenche. Comment faire ça avec la librairie boost::asio ? Chacune de mes tentatives ont été des échecs.
J'avais un serveur qui écoutait sur un port x. Un client (qui avec une autre socket) envoyait ses données sur le même port (à une adresse spécifique). Cependant lorsque le client se mettait en route, le serveur ne recevait plus aucun paquet. Je me demandais donc si il n'y avait pas une façon plus simple d'envisager la chose.
Question 3
Je dois gérer une interface utilisateur que je compte encapsuler dans une classe. L'interface devra être exécutée dans un thread particulier. Afin de faire ça, est-ce recommandable d'utiliser une méthode run qui sera implémentée par la classe UI ? Ou bien il existe une façon plus idiomatique de le faire ?
Question 4
Le programme peut choisir la façon dont sera stocké les données récupérées grâce à une option sur la ligne de commande. Les options sont gérés avec boost_program_options. Lorsque ce choix se fait sur une certaine BDD, comme ce choix étant connu au début de l'éxécution, je me demandais s'il était pas préférable que le module qui gère les options renvoie directement un pointeur sur la BDD plutôt que ce soit l'utilisateur de la classe qui le fasse lui-même. Est-ce pertinent ? Ou bien ça n'a aucune importance ?
Question 5
Je souhaite sécurisé mes données en donnant comme identifiant à mes données un hash. Je pensais donc utiliser MD5 ou SHA-1. J'ai été surpris de voir que Boost ne proposait pas ces deux méthodes. Le recours à CryptoC++ est le meilleur moyens de faire ça ?
Le second problème vient du fait que l'identifiant doit faire 8 bytes, alors que les hash sont plus élevés. J'applique donc une fonction sur les bytes obtenus pour en avoir que 8. Est-ce finalement une bonne méthode d'utiliser MD5 ou SHA-1 , ou bien il existe une meilleure solution ?
Question 6
J'a regardé rapidement, mais il existe une framework pour mettre en place facilement des tests unitaires ? Il y a CUTE, mais j'ai pas encore pris le temps de regarder si c'était vraiment rapide à mettre en place.
Je crois que c'est à peu près tout niveau question. Si vous voulez un accès au code source je pourrais le mettre en ligne sur git ce soir. Il est partiellement commenté (pour les .h) en utilisant doxygen.
Merci d'avance pour tous les commentaires que vous pourrez me suggérer,
Bonne soirée