IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Lire un header en C++


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juillet 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juillet 2009
    Messages : 31
    Points : 28
    Points
    28
    Par défaut Lire un header en C++
    Bonjour,
    Alors, je dois développer un serveur TFTP en C++. Mon équipe bosse constamment avec boost, j'ai donc choisi asio pour la partie réseau.
    Je suis plutôt novice en ce qui concerne la programmation réseau, et ce sont mes premiers pas avec le protocole UDP.
    Comme base du serveur, j'utilise l'exemple du serveur écho async UDP.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    class server
    {
    public:
        server(boost::asio::io_service& io_service, short port)
        : io_service_(io_service),
        socket_(io_service, udp::endpoint(udp::v4(), port))
        {
            ...
        }
     
        void handle_receive_from(const boost::system::error_code& error,
                                 size_t bytes_recvd)
        {
            if (!error && bytes_recvd > 0)
            {
                socket_.async_send_to(
                                      boost::asio::buffer(data_, bytes_recvd), sender_endpoint_,
                                      boost::bind(&server::handle_send_to, this,
                                                  boost::asio::placeholders::error,
                                                  boost::asio::placeholders::bytes_transferred));
            }
            else
            {
                ...
            }
        }
        ...
        }
     
    private:
        boost::asio::io_service& io_service_;
        udp::socket socket_;
        udp::endpoint sender_endpoint_;
        enum { max_length = 1024 };
        char data_[max_length];
    };
    En ouvrant un client TFTP et en faisant une demande simple:
    TFTP> get truc.txt

    je peut lire dans mon server (dans le bout de code plus haut), dans ma chaine data_ :
    \0\x01/truc.txt\0netascii\0

    C'est bien ce qui est attendu, donc jusqu'ici je suis content.

    Maintenant, j'ai une question qui pourrait vous sembler triviale, mais comment je lis ça de la façon la plus "élégante" ?
    Comment lire les 2 premiers bytes afin d'avoir le code d'opération (1 dans cet exemple) ?
    Je n'ai jamais eu à faire ce genre de truc et j'ai du mal à trouver des infos...

    Merci de m'avoir lu !

  2. #2
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    Pour lire les deux premiers bytes c'est simple. Tu as un tableau de char...
    bytes en français c'est octet.
    char == 1 octet == 8 bits.
    Donc lire les 2 premiers "bytes" c'est lire data_[0] et data_[1].
    Homer J. Simpson


  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juillet 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juillet 2009
    Messages : 31
    Points : 28
    Points
    28
    Par défaut
    Merci Astraya, j'ai donc lu "simplement" ces 2 premiers octets.

    Ensuite, je dois "découper" ma chaine, mais pas moyen d'utiliser un tokenizer (enfin... j'ai pas réussi...) puisque le séparateur est '\0', la fin de chaine.
    J'ai simplement parcouru la chaine à la recherche des premières occurrence du caractère, puis j'en ai extrait les chaines :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    bool decode_data()
        {
            bool ok = true;
     
            if (data_[0] != '\0')
            {
                // ERROR - TODO
                ok = false;
     
            }
            if (ok && data_[1] == '\1')
            {
                // put op
                opCode = 1; // RRQ
     
            }
            else if (ok && data_[1] == '\2')
            {
                // put op
                opCode = 2; // WRQ
     
            }
            else
            {
                // ERROR - TODO - UNKNOWN CODE
                ok = false;
            }
            int firstSeparator, endSeparator;
            if (ok)
            {
                bool firstSearch = true;
                bool out = false;
     
                for (int i=2; !out && i < max_length; i++)
                {
                    if (data_[i] == '\0')
                    {
                        if (firstSearch)
                        {
                            firstSeparator = i;
                            firstSearch = false;
                        }
                        else
                        {
                            endSeparator = i;
                            out = true;
                        }
                    }
                }
                if (!out)
                {
                    // ERROR - TODO - SYNTAX ERROR
                    ok = false;
                }
            }
            if (ok)
            {
                fileName = std::string(data_ + 2, data_ + firstSeparator);
                transferMode = std::string(data_ + firstSeparator + 1, data_ + endSeparator);
     
                std::cout <<  (opCode == 1 ? "RRQ" : "WRQ")
                    << " - file:\"" << fileName
                    << "\" - mode:" << transferMode << std::endl;
            }
            return ok;
        }
    Ca a l'air de marcher, mais c'est assez "lourd". Y a-t-il un moyen plus "élégant" et sécurisé d'utiliser '\0' comme séparateur ?

    Merci

  4. #4
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    As tu fais des recherches sur internet? std::string + split? il y a plein d'exemple
    Homer J. Simpson


  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juillet 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juillet 2009
    Messages : 31
    Points : 28
    Points
    28
    Par défaut
    Oui, j'ai déjà utilisé split, mais j'ai l'impression que ma chaine n'est pas lue en entier, mais seulement jusqu'au premier "\0" puisqu'il équivaut à la fin de la chaine.

    EDIT:
    Je confirme.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::vector<std::string> strs;
    boost::split(strs, data_, boost::is_any_of("\0"));
    ne parcourt pas toute la chaine, je viens de tester.

  6. #6
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    Je pense que utiliser le caractère de fin de chaine en tant que séparateur n'est pas étranger à ton problème. Car je te rassure, boost fonctionne très bien.
    Change ton séparateur .
    Homer J. Simpson


  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juillet 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juillet 2009
    Messages : 31
    Points : 28
    Points
    28
    Par défaut
    Mais je ne peux pas changer le séparateur, il fait partie du protocole TFTP, et c'est ce que m'enverra n'importe quel client !

  8. #8
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    Bien sur que si: boost::replace_all

    Sinon tu fait un boucle for toi même pour couper ton buffer en plusieurs std::vector<std::string>> si tu connais la taille de ta trame c'est facile.
    Homer J. Simpson


  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juillet 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juillet 2009
    Messages : 31
    Points : 28
    Points
    28
    Par défaut
    Merci encore, j'ai choisi de parcourir le char*, je ne cherche de toute façon que 2 chaines.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. lire un fichier de donnees sans le header
    Par follichon dans le forum MATLAB
    Réponses: 1
    Dernier message: 17/01/2013, 13h10
  2. lire et écrire un header http customisé
    Par mpoys dans le forum ASP.NET
    Réponses: 1
    Dernier message: 28/10/2010, 10h18
  3. [ELF] Lire un header
    Par robertledoux dans le forum Linux
    Réponses: 1
    Dernier message: 14/03/2009, 17h39
  4. Lire les entêtes (headers)
    Par coolcoco dans le forum Langage
    Réponses: 2
    Dernier message: 24/10/2007, 10h57
  5. lire a partie d'un header
    Par 4daime dans le forum C++
    Réponses: 8
    Dernier message: 14/08/2007, 22h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo