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

Réseau C Discussion :

Probleme calcule checksum


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut Probleme calcule checksum
    Bonjour,

    Alors voila ... Dans l'application que je dois réalisé, je dois faire un calcule d'un checksum (la facon de calculer le checksum a été défini a l'avance dés deux cotés pour que l'on ai le meme calcule) ... Mais le probleme est que ca prend des valeurs bizzar ... Que ca ne sort pas les valeurs escomptées ...

    Voici dans un premier temps le code source :
    Code C : 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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <winsock2.h> 
     
    unsigned short checksum(void *addr, int len);
     
    struct statMeasReq{ 
      char control;
      char lenght;
      unsigned short checksum;
      unsigned short packetID;
    };
     
    int main(void){
     
       int size;
     
       // Création d'un pointeur vers la structure.
       struct statMeasReq *packet;
     
       // Allocation de la taille.
       packet = (struct statMeasReq *)malloc(sizeof(struct statMeasReq));
     
       // Mise a zéro 
       memset(packet, 0x0, sizeof(struct statMeasReq));
       ZeroMemory(packet, sizeof(packet)); //mise à zero
     
       // Garnissage.
     
       packet->control = 0x02;
       packet->lenght = 6;
       packet->checksum = 0;
       packet->packetID = 1;
       packet->checksum = checksum(packet, 6);
     
       free(packet);  
     
       system("PAUSE");
       return 0;
    }
     
    unsigned short checksum(void *addr, int len){
     
      int nleft = len;
      unsigned short *w = addr;
      int sum = 0;
      unsigned short answer = 0;
     
      // Somme des données pris deux par deux.
      while (nleft > 1) {
            sum += *w;
            w++;
            nleft -= 2;
      }  
     
      // Calcule du complément à 1 sur 16bits.
      answer = ~sum;
     
      // Envoie de la valeur du checksum calculé.
      return (answer);
    }

    Voila ... J'espere que vous avez compris mon probleme ... Si jamais je me tien a votre disposition pour répondre à vos questions.

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    1. On ne caste pas le retour de malloc() en C.
    2. Pourquoi cumules-tu memset() et ZeroMemory() ?
    3. Il faut passer sizeof(*paquet) à ZeroMemory().
    4. Ta fonction checksum devrait prendre un const void * en paramètre.
    5. D'où sort le 6 exactement ?

    Quelles sont les valeurs escomptées et obtenues ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut
    Bonjour,

    Déjà, merci de ton aide ...

    Alors voila:

    1. Ha bon ? Donc je peux enlever le :

    2. Oups ... C'est vrai que les fonctions ont toute les deux la même fonction ... Peut etre lors d'un test j'ai oublié d'en enlever une.

    3. Je vais le supprimer alors ... Vu que memeset est suffisant.

    4. A partir du moment ou je ne touche pas a la variable ... Ca n'a pas d'importance si je la met en const ... Enfin je pense

    5. Le 6 corrspond a la taille de mon "packet" dont je voudrais calculer le checksum ... (les packets ont une taille bien definie ... Donc j'envoie direct ca taille).

    Voila ce que j'obtien pour sum dans la boucle :
    Sum : 1538
    Sum : 1538
    Sum : 1539
    et le checksum en sortie : 63996

    Alors que je devrais avoir dans les 1500 je pense ...
    valeur pour le calcule :
    control : 2
    lenght : 6
    checksum : 0
    packetID : 1
    voir meme 508 avec le complement a 1 si je ne m'abbuse et si mes calcules sont bons

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ben non, ça me parait correct :
    • 2 + 256*6 = 1538 (parce que le x86 est une architecture little-endian)
    • 1538 + 0 = 1538
    • 1538 + 1 = 1539
    • ~1539 = 63996
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut
    Hum ... Ui ...

    Tu as raison c'est vrai ... Lol ... C'est de l'autre coté alors qu'il calcule mal ....
    Pfff ... Moi qui me casse la tete alors que ca a l'air bon ...

    Mais bon j'suis qu'un étudiant en stage ... Je me suis dis que l'erreur venait surment de moi ... Enfin ... Merci ...

    C'est très gentil de ta part de m'avoir montré que j'avais raison ... j'espere que mon maitre de stage va le comprendre aussi ...

    Bien a vous, Vincent.

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Sauf qu'il est effectivement possible que tu calcules mal: La première ligne me parait étonament suspecte, quand on sait que le format "réseau" est supposé être big-endian...

    En big-endian, ça donnerait ceci:
    • 6 + 256*2 = 518
    • 518 + 0 = 518
    • 518 + 1 = 519
    • ~519 = 65016
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Fio,
    Citation Envoyé par nuFox Voir le message
    5. Le 6 corrspond a la taille de mon "packet" dont je voudrais calculer le checksum ... (les packets ont une taille bien definie ... Donc j'envoie direct ca taille).
    Ce n'est pas garanti, il y a de fortes chances que le compilateur aligne les données en fonction du processeur cible.

    Et je trouve curieux d'inclure le champ checksum dans le calcul du checksum : quand tu auras mis la valeur trouvée dans le champ, le checksum sera modifié, etc.

  8. #8
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut
    Non puisque je genere le packet sur ma machine ... et je l'envoie avec une fonction send ... En faisant un strlen le probleme est que s'il rencontre un zero il le compte comme fin de chaine ... Hors dans mon cas, je connais la taille des packet que je dois envoyer.. Alors autant lui indiquer desuite

    Si on calcule le checksum avec une valeur de zero ... ca ne change rien ... Il suffit que de l'autre cote, il remette le champs checksum a zero et le recalcule (en ayant biensur sauvegardé la valeur avant ^^ lol)

  9. #9
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Gie,
    Citation Envoyé par nuFox Voir le message
    Non puisque je genere le packet sur ma machine ... et je l'envoie avec une fonction send ... En faisant un strlen le probleme est que s'il rencontre un zero il le compte comme fin de chaine ... Hors dans mon cas, je connais la taille des packet que je dois envoyer.. Alors autant lui indiquer desuite
    Mais il est tout de même prudent d'utiliser sizeof, ne serait-ce que pour en conserver l'habitude.

    Citation Envoyé par nuFox Voir le message
    Si on calcule le checksum avec une valeur de zero ... ca ne change rien ... Il suffit que de l'autre cote, il remette le champs checksum a zero et le recalcule (en ayant biensur sauvegardé la valeur avant ^^ lol)
    Il serait plus simple d'exclure le champ checksum du calcul (ce qui implique de le mettre à la fin de la structure, et, pour faciliter, de créer une sous-structure pour les autres champs).

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

Discussions similaires

  1. probleme calcule somme
    Par debutantasp dans le forum ASP
    Réponses: 2
    Dernier message: 19/03/2008, 13h17
  2. Réponses: 4
    Dernier message: 30/05/2007, 16h44
  3. probleme calcul
    Par cflo91 dans le forum Prolog
    Réponses: 4
    Dernier message: 16/05/2007, 09h34
  4. Probleme calcul Delphi
    Par kennes dans le forum Delphi
    Réponses: 4
    Dernier message: 19/11/2006, 01h00
  5. [LG] Problème calcul de trinome
    Par shinryu666 dans le forum Langage
    Réponses: 3
    Dernier message: 24/09/2005, 09h38

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