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 :

vector<byte> n'est pas d'accord.


Sujet :

C++

  1. #21
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par DakM Voir le message
    Oui mais je recois en tant que char*, n'est-il pas couteux de faire une convertion vers un string au lieu de rester sur du char* et de bosser avec ca ?
    Pas outre mesure : il existe un constructeur de string prenant un char * en paramètre qui te permet meme de passer directement ton char* à la fonction

    [EDIT]En outre, il faut vérifier, mais si tu suis mon conseil de te tourner vers boost asio pour la gestion de tes socket, je serais surpris que tu ne puisse pas récupérer les informations directement sous la forme de std :: string
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  2. #22
    Membre régulier
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Points : 99
    Points
    99
    Par défaut
    Etant donné que je ne suis pas bon, je preferes pour l'instant ne pas utiliser de grosses biblio lourdes et dont je n'utiliserais pas 1% des fonctionnalités !

  3. #23
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Citation Envoyé par DakM Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    		cout << "byte " << i << Packet.bytes[i] << endl;
    Si bytes est de type char, la sortie n'est pas numérique mais le charactère correspondant, c'est à dire probablement quelque chose de farfelu si hors de la plage des caractères ASCII affichables. Forces le type numérique pour voir la valeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cout << "byte " << i << std::hex<< static_cast<unsigned>(Packet.bytes[i]) << endl;
    S'il s'agit d'octets reçus et à traiter en tant que tels, il vaut mieux utiliser un type non signé : struct Packet{std::vector<unsigned char> bytes};
    Citation Envoyé par DakM Voir le message
    Etant donné que je ne suis pas bon, je preferes pour l'instant ne pas utiliser de grosses biblio lourdes et dont je n'utiliserais pas 1% des fonctionnalités !
    C'est à peu près l'inverse qui est recommandé : utilise des bibliothèques éprouvées si tu débutes, tu bénéficiera de facto de l'expérience de ceux qui l'ont construite. Faire par soi même quand on ne maîtrise pas, c'est la meilleure façon de faire le plus de bug possible.

  4. #24
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Citation Envoyé par DakM Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    // char* substr(char*, int, int); -> cf. manuel PHP. Pareil ^^
    Citation Envoyé par DakM Voir le message
    Fonction substr():
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int substr(char *s, int start, int length) {
    	char t[2] = {s[start], s[(start+length)]};
    	return (int)strtol(t, NULL, 16);
    }

    (Hé oui, elle est spécifique)
    Hum...
    Tu te contredis...

    J'ajouterais juste aux remarques de koala01 que la fonction strtol attend une chaîne de caractères terminée par un caractère nul en premier paramètre.
    Et vu comment tu l'appelles, il n'y a aucun moyen de le garantir, ni même de le prévoir.
    Ce problème serait résolu en écrivant quelque chose comme ceci (modulo les modifications adéquates, cf. remarques de koala01) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char t[] = {s[start], s[(start+length)], '\0'};

  5. #25
    Membre régulier
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Points : 99
    Points
    99
    Par défaut
    Vraiment c'est étrange le C++. Il y a un truc que j'capte pas ici.

    Voici un screen de VS durant le debug!

    http://img847.imageshack.us/img847/5863/wtfffffn.png

    On voit le char* buffer, avec 01 00 01 ...
    Et on voit packet, avec 1 ' ', 0, 1 ' ', 0,0,0,0,0 ....
    C'est quoi ce blanc ? (Il correspond aux smiley qui s'affichent sur l'écran au lieu des 0 ...)

    Sinon eh bien, mes chars ne vont toujours pas dans mon vector, (enfin ils y vont, mais je n'arrivent pas à les lires!

    voici substr, mais changée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char getbyte(char *s, int at) {
    	char t[3] = {s[at], s[(at+1)], '\0'};
    	return (char)strtol(t, NULL, 16);
    }
    voici là ou je construit mon vector<unsigned char> (changé de byte!)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    XServer::Packet PacketFactory::CreatePacket(char *s) {
    	len = strlen(s);
    	bytes = floor((float)len/2)-floor((float)len/6);
    	for(int i=1; i<=bytes; ++i) {
    		cout << "Pushing " << getbyte(s, (i-1)*3) << endl;
    		Packet->bytes.push_back(getbyte(s, (i-1)*3));
    	}
    	Packet->index = 0;
    	cout << "Created packet : " << Packet->bytes.size() << endl;
    	for(int i=0; i<bytes; ++i) {
    		cout << "byte " << i << Packet->bytes.at(i) << endl;
    	}
    	return *Packet;
    }
    Rien que sur le premier cout, j'obtient à l'écran
    Pushing
    Pushing
    Pushing
    Pushing
    ...

  6. #26
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Citation Envoyé par koala01 Voir le message
    @ DakM : j'aimerais en savoir plus sur les valeurs que tu reçois, et surtout sur le protocole qui te permet de les recevoir.
    Il me semble, au point où nous en sommes, que, pour toi, la chose essentielle à faire pour avancer est de tout mettre en œuvre pour répondre à cette question !! (ou bien doit-on comprendre que tu traites des données dont tu ne connais pas vraiment la nature ??)

  7. #27
    Membre régulier
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Points : 99
    Points
    99
    Par défaut
    Il me semble avoir deja répondu à ca.

    Le client & le serveur communique en "hexadecimal".

    Exemple, pour que le client s'identifie, il enverra:

    01 04 6e 69 63 6f 0a 6d 6f 74 64 65 70 61 73 73 65
    01 = header du packet qui dira au server que le client essaye de s'identifier.
    04 = longueur de l'identifiant.
    6e 69 63 6f = identifiant (nico)
    0a = longueur du MDP.
    6d 6f 74 64 65 70 61 73 73 65 = motdepasse

    Et le serveur, en fonction des verifications aupres de la BD. répondra
    01 01 (connecté!)
    ou
    01 02 (acces refusé!)

    Et ca continue !

  8. #28
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Juste histoire d'être sûr...
    Désolé d'en remettre une couche, mais je pense qu'il vaut mieux passer suffisamment de temps pour bien comprendre ça, plutôt que de ne pas partir sur les mêmes bases et s'en rendre compte dans 3 ans...

    strlen("01 04 6e 69 63 6f 0a 6d 6f 74 64 65 70 61 73 73 65") vaut 17 ou 50 ?

  9. #29
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par DakM Voir le message
    Il me semble avoir deja répondu à ca.

    Le client & le serveur communique en "hexadecimal".
    Non, tu n'avais jamais répondu à cela, autrement, nous n'aurions pas insisté pour que tu nous le dise

    Maintenant, nous allons pouvoir t'aider

    Exemple, pour que le client s'identifie, il enverra:

    01 04 6e 69 63 6f 0a 6d 6f 74 64 65 70 61 73 73 65
    01 = header du packet qui dira au server que le client essaye de s'identifier.
    04 = longueur de l'identifiant.
    6e 69 63 6f = identifiant (nico)
    0a = longueur du MDP.
    6d 6f 74 64 65 70 61 73 73 65 = motdepasse

    Et le serveur, en fonction des verifications aupres de la BD. répondra
    01 01 (connecté!)
    ou
    01 02 (acces refusé!)

    Et ca continue ![/QUOTE]Bon, maintenant, nous pouvons te proposer une solution.

    La première chose à faire, c'est bien de récupérer ce que le serveur envoie sous la forme de unsigned char non pas dans un unsigned char * mais dans un std::vector< unsigned char>.

    Tu n'auras alors même plus à t'inquiéter de la conversion, parce que ce que tu obtiens est déjà... un tableau de byte!

    Et cela t'évitera un tas de problème du fait des caractères non affichables (parce que tu ne considère pas ce que tu obtiens comme l'index de la table ASCII mais bien comme... une valeur numérique de petite taille).

    Tous tes problèmes viennent de là!

    Comme je te l'ai dit plus haut '1' ne vaut pas 1 !!!

    1 en tant que valeur (en tant qu'index dans la table ASCI) est est caractère non affichable SOH (Start Of Header) alors que '1' en tant que représentation graphique se trouve en réalité à l'index... 49 (décimal) ou, en hexadécimal 0x31.

    Si j'insiste là dessus, c'est parce qu'il est important que tu comprennes la différence.

    Pour faire un parallèle, '1' sera ce que tu lira en ouvrant un fichier texte avec notepad (ou autre) alors que 1 sera ce que tu obtiens en lisant un fichier binaire.

    Ici, ce que tu obtiens, c'est un flux équivalent à un fichier binaire, tu ne peux donc pas le gérer comme si c'était du texte!
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #30
    Membre régulier
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Points : 99
    Points
    99
    Par défaut
    Citation Envoyé par Steph_ng8 Voir le message
    Juste histoire d'être sûr...
    Désolé d'en remettre une couche, mais je pense qu'il vaut mieux passer suffisamment de temps pour bien comprendre ça, plutôt que de ne pas partir sur les mêmes bases et s'en rendre compte dans 3 ans...

    strlen("01 04 6e 69 63 6f 0a 6d 6f 74 64 65 70 61 73 73 65") vaut 17 ou 50 ?
    Eh bien si je recois dans mon char* buffer, strlen=50.
    Ensuite pour récuperer le nombre de bytes, je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    floor((float)strlen(buf)/2)-floor((float)strlen(buf)/6)
    ensuite je lit chaque byte avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	for(int i=1; i<=bytes; ++i) {
    		cout << "Pushing " << getbyte(s, (i-1)*3) << endl;
    		Packet->bytes.push_back(getbyte(s, (i-1)*3));
    	}
    Donc pour le byte 1, je vais ajouter a ma pile le charactere (i-1)*3 et celui qui suit. Et transformer ca en hex (ce que doit faire ma fonction getbyte.)


    Citation Envoyé par koala01 Voir le message
    Non, tu n'avais jamais répondu à cela, autrement, nous n'aurions pas insisté pour que tu nous le dise

    Maintenant, nous allons pouvoir t'aider

    [..]
    Bon, maintenant, nous pouvons te proposer une solution.

    La première chose à faire, c'est bien de récupérer ce que le serveur envoie sous la forme de unsigned char non pas dans un unsigned char * mais dans un std::vector< unsigned char>.

    Tu n'auras alors même plus à t'inquiéter de la conversion, parce que ce que tu obtiens est déjà... un tableau de byte!

    Et cela t'évitera un tas de problème du fait des caractères non affichables (parce que tu ne considère pas ce que tu obtiens comme l'index de la table ASCII mais bien comme... une valeur numérique de petite taille).

    Tous tes problèmes viennent de là!

    Comme je te l'ai dit plus haut '1' ne vaut pas 1 !!!

    1 en tant que valeur (en tant qu'index dans la table ASCI) est est caractère non affichable SOH (Start Of Header) alors que '1' en tant que représentation graphique se trouve en réalité à l'index... 49 (décimal) ou, en hexadécimal 0x31.

    Si j'insiste là dessus, c'est parce qu'il est important que tu comprennes la différence.

    Pour faire un parallèle, '1' sera ce que tu lira en ouvrant un fichier texte avec notepad (ou autre) alors que 1 sera ce que tu obtiens en lisant un fichier binaire.

    Ici, ce que tu obtiens, c'est un flux équivalent à un fichier binaire, tu ne peux donc pas le gérer comme si c'était du texte!
    J'ai bien compris la difference entre 0x01 et 0d01
    Comment faire pour faire un recv() sur un socket qui transforme la reception (donc quelque chose du style 01 01 01 01) en vector<unsigned char> directement, sans passer par mes fonctions ?
    Car VS ne veux meme pas que j'utilises de std::string... (D'ou mon choix de ne pas utiliser ca ..)

    nico

  11. #31
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par DakM Voir le message
    J'ai bien compris la difference entre 0x01 et 0d01
    Comment faire pour faire un recv() sur un socket qui transforme la reception (donc quelque chose du style 01 01 01 01) en vector<unsigned char> directement, sans passer par mes fonctions ?
    Car VS ne veux meme pas que j'utilises de std::string... (D'ou mon choix de ne pas utiliser ca ..)

    nico
    Exactement comme je le dis depuis le début:
    • utilise un tableau de unsigned char ( donc avec un unsigned char* buffer, si tu veux )
    • manipule ce tableau non pas comme s'il s'agissait d'une chaine de caractères mais bien comme ce que c'est réellement à savoir : un tableau de valeurs numérique, ce qui revient à... ne pas utiliser la moindre fonction strXXX

    Si tu suit ces deux instructions toutes bêtes, tu auras beaucoup moins de problèmes

    Mais, j'y penses... le serveur, est-ce toi qui t'en occupe

    Montre nous un peu la partie qui construit la réponse et qui l'envoie, STP...

    De cette manière, nous pourrons avoir la certitude de la manière dont les données sont émise
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #32
    Membre régulier
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Points : 99
    Points
    99
    Par défaut
    Je n'ai meme pas fais le client encore, dabord je fais mon serveur (qu'il puisse traiter les packet et que les threads marchent bien, ensuite je ferais le client ! =)

    Le truc que je ne comprend pas, cmment utiliser recv() avec un unsigned char *buffer pour pouvoir le traiter avec des valeurs numériques...
    La fonction c'est recv(SOCKET, char*, int, int);

  13. #33
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par DakM Voir le message
    Je n'ai meme pas fais le client encore, dabord je fais mon serveur (qu'il puisse traiter les packet et que les threads marchent bien, ensuite je ferais le client ! =)

    Le truc que je ne comprend pas, cmment utiliser recv() avec un unsigned char *buffer pour pouvoir le traiter avec des valeurs numériques...
    La fonction c'est recv(SOCKET, char*, int, int);
    Peut etre as tu alors une spec du protocole à utiliser

    Laisses moi deviner, vas tu me poser la question de "c'est quoi une specs?" maintenant

    Quoi qu'il en soit, je ne peux que répéter ma recommandation d'utiliser boost asion pour l'ensemble de ton projet.

    Les tutoriaux aidant, tu arriveras beaucoup plus facilement et rapidement à un résultat correct et qui plus est portable que si tu dois apprendre à gérer tes sockets et tes threads avec les bibliothèques C et sous window!

    Le propre d'un bon programmeur, lorsqu'il est confronté à un problème qu'il n'a jamais rencontré n'est pas forcément de s'arracher les cheveux à tout faire par lui-même, mais de commencer par voir si, par hasard, il n'existerait pas une bibliothèque éprouvée qui puisse lui servir de base!

    Nous avons d'ailleurs eu, il y a quelques mois, un débat fort intéressant sur l'utilisation de bibliothèques et le syndrome NIH (Not Implemented Here)

    Quand on pense que boost sera ton "compagnon de voyage au pays de C++" exactement au même titre que la STL, on se dit qu'il serait vraiment aberrant, meme pour un débutant, meme si c'est pour n'utiliser qu'une des bibliothèque qu'elle offre, alors que tu ne vois meme pas comment convertir un char* en unsigned char *, ce qui semble indiquer qu'il te manque peut etre quelque notions de base en C++ !

    Plus vite tu prendras l'habitude d'écrire du C++ et non du C et plus vite tu te mettras à l'utilisation de la STL et de parties de boost qui t'apparaitront utiles pour les besoins que tu rencontre de manière journalière, plus vite tu pourras évoluer et devenir efficace en C++!!!
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Programmer encore en VB 6 c'est pas bien ? Pourquoi ?
    Par Nektanebos dans le forum Débats sur le développement - Le Best Of
    Réponses: 85
    Dernier message: 10/03/2009, 14h43
  2. Réponses: 10
    Dernier message: 30/06/2008, 19h59
  3. LIKE de tout ce qui n'est pas compris entre a<-&
    Par DjinnS dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 28/07/2003, 13h09
  4. [VB6] générer un recordset qui n'est pas lier à un bdd
    Par damyrid dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 05/06/2003, 17h48
  5. Index n'est pas a jour
    Par touhami dans le forum Paradox
    Réponses: 5
    Dernier message: 11/12/2002, 14h47

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