Forum Programmation.c++ choix pour l'écriture d'un serveur en C++

Posté par  .
Étiquettes : aucune
0
28
mar.
2008
Bonjour
Je dois ré-écrire la partie réseau d'un démon en C++, et donc je cherche une bonne solution pour cela. Le démon doit pouvoir recevoir des commandes et les interpréter, commandes provenant d'utilisateurs connectés avec telnet ou d'autres programmes qui se connecteraient sur le port ouvert du démon.

Je cherche des conseils sur les techniques/bibliothèques à utiliser, pour s'affranchir le plus possible des problèmes auquel je m'attends : format des messages (comment détecter la fin des commandes, les interpreter, encodages, etc), gestion des sockets, etc
  • # Sockets C - C++

    Posté par  . Évalué à 6.

    J'ai eu le même problème et franchement, j'ai fini par refaire mes propres classes. Pour deux raisons :

    - Les libs que l'on trouve sur la toile sont soit des APIs Windows, soit des outils qui ont été faits dans les mêmes conditions que les tiennes. Il n'y a donc aucune garantie que ces trucs soient plus propres ni plus faciles à utiliser que ce que tu vas produire. Honnêtement, je n'ai pas cherché plus longtemps que çà non plus, mais si ce n'est pas destiné à un gros projet open-source servant de référence et repris par des dizaines de personnes, la recherche et l'investissement personnel deviennent plus importants que la rédaction de son propre code (ce n'est évidemment pas vrai pour tous les cas de figure).

    - L'API des sockets BSD est à s'arracher les cheveux car c'était à la base une tentative d'universalisation de tous les modes de communication, et il ont essayé de couvrir large dès le départ. C'était une bonne idée, mais maintenant on se traîne depuis des décenies des choses qui ne servent à rien.

    D'autre part, il y avait clairement une notion d'abstraction et de classification qui sont aujourd'hui caractéristiques de la programmation objet. Citons par exemple la notion d'adresse réseau sockaddr étendue en sockaddr_in mais par redéfinition. Même pas un union de structures puisque les familles de protocoles sont déclarées à postériori. Dans cette structure, une autre structure pour l'adresse en particulier, in_addr, laquelle ne contient en tout et pour tout qu'un seul et unique membre, un long de 32 bits !

    A l'utilisation, on est obligé d'utiliser des cast explicites pour transformer un sockaddr_in en sockaddr général pour ne pas prendre de warnings à la compilation. Coté init, c'est pas triste non plus : le modèle a beau être cohérent, il est implémenté de telle manière que tout est à la charge du développeur : hton{sl}() à tout bout de champ à chaque fois qu'il faut changer une adresse, et obligé de spécifier à l'intérieur de chaque structure pourtant déjà spécialisé le type d'adresse (AF_INET), simplement pour que les fonctions dont on a dû abstraire les paramètres puisse les recaster dans l'autre sens en connaissance de cause. Au secours !

    Par contre ...

    ... par contre, encapsuler tout ce merdier dans des classes n'est pas plus compliqué que d'écrire un programme réseau classique en C pour quelqu'un qui s'y est déjà collé, et on se retrouve au final avec trois ou quatre objets maximum, lequels ne sont pas dérivés plus loin. Du coup, la programmation des sockets qui a l'air si difficile en C semble très simple même avec ses propres objets.


    Donc, d'expérience, ce qui est utile pour écrire un daemon text-based est :

    - Ses propres sockets (ci-dessus).
    - Un analyseur de regexp (en encapsulant encore les routines C système).
    - Un mini-parser. Pas besoin de réécrire yacc, mais il n'y a rien de mieux qu'une grammaire BNF pour décrire la syntaxe d'une ligne valide.
    - Un petit automate à pile. On trouve les classes, cette fois, mais ce n'est pas bien dur non plus de refaire le sien une fois pour toutes.

    A partir de là, tu peux déclencher un événement sur n'importe quel flux d'entrée. En te démerdant bien, tu peux faire un programme complètement coopératif sans avoir besoin de pondre un thread.

    Bon courage.
    • [^] # Re: Sockets C - C++

      Posté par  . Évalué à 6.

      Pour le réseau, la bibliothèque asio http://asio.sourceforge.net/ est pas mal du tout. Et pour les regex, boost dispose d'une bibliothèque pour cela (ou bien pcre++ qui est un wrapper assez fin en C++ autour de la bibliothèque pcre).

      Étienne
      • [^] # Re: Sockets C - C++

        Posté par  . Évalué à 4.

        Je suis d'accord, asio est une très bonne librairie réseau, bien pensée, et utilisée par plusieurs gros projets et a été minutieusement décortiquée par le projet boost qui l'a intégré.
        asio est même considéré pour être intégré dans la librairie standard dans un futur plus ou moins lointain (cf TR2).

        Pour le parsing, à la place (ou en complément) des regex de boost (compatible avec c++0x) on peut utiliser spirit qui permet de décrire avec une syntaxe proche de EBNF.

        http://spirit.sourceforge.net/
  • # QtCore / QtNetwork

    Posté par  (site web personnel) . Évalué à 6.

    Qt:
    Avec les classes QTcpSocket et QTcpServer pour la gestion des sockets
    et QString, QRegExp, QTextStream pour la gestion des commandes

    Et tout le reste de QtCore (listes, objects, thread) va accélérer ton développement, j'en suis sur
  • # inetd/xinetd

    Posté par  (site web personnel) . Évalué à 5.

    Est-ce que ce sont des solutions que tu as envisagées ? Ca a le mérite de t'éviter de réecrire tout le protocole de communication non ?

    « IRAFURORBREVISESTANIMUMREGEQUINISIPARETIMPERAT » — Odes — Horace

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.