Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Bug, un caractère en trop dans mon paquet pour les packets perso.  (Lu 21383 fois)

0 Membres et 1 Invité sur ce sujet

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Salut, j'ai fait un test avec du code, mais j'ai toujours un caractère en trop au début du paquet que j'envoie, voici ce que je fait dans la fonction onSend :
 const char* datas = static_cast<const char*> (getData());
    buffer.assign(datas, datas + getDataSize());
    vector<char>::iterator it;
    string message;
    for (it = buffer.begin(); it != buffer.end(); it++)
         message += *it;
    cout<<"Message : "<<message<<endl;
    for (unsigned int i = 0; i < message.size(); i++)
        buffer.push_back(message.at(i));
    dataSize = buffer.size();
    return &buffer[0];
 
Lorsque j'affiche le message en console il me rajoute à chaque fois un caractère en trop dans le début du message.
« Modifié: Juin 24, 2013, 02:05:14 pm par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Bug, un caractère en trop dans mon paquet pour les packets perso.
« Réponse #1 le: Juin 24, 2013, 01:37:21 pm »
Ce serait bien de voir un code complet minimal.

Il va falloir que je le dise à chaque fois, ou bien... ?
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Bug, un caractère en trop dans mon paquet pour les packets perso.
« Réponse #2 le: Juin 24, 2013, 02:04:17 pm »
Le voici, code côté serveur :

#include <SFML/Network.hpp>
#include <iostream>
#include <vector>
using namespace sf;
using namespace std;
#include "symEncPacket.h"
int main () {
    vector<TcpSocket*> clients;
    TcpListener listener;
    SocketSelector selector;
    if (listener.listen(4567) == Socket::Done)
        cout<<"Ok"<<endl;
    selector.add(listener);
    string message;
    while (true) {
        if (selector.wait()) {
            if (selector.isReady(listener)) {
                TcpSocket *client = new TcpSocket();
                if (listener.accept(*client) == Socket::Done) {
                    cout<<"Client connected"<<endl;
                    selector.add(*client);
                    clients.push_back(client);
                }
            }
            for (unsigned int i = 0; i < clients.size(); i++) {
                if (selector.isReady(*clients[i])) {
                    SymEncPacket packet;
                    if (clients[i]->receive(packet) == Socket::Done) {
                        string message;
                        packet>>message;
                        //cout<<"Received from client (TCP) : "<<message<<endl;
                        packet.clear();
                        message = "Ceci est un message TCP!";
                        packet<<message;
                        clients[i]->send(packet);
                    } else {
                        selector.remove(*clients[i]);
                        vector<TcpSocket*>::iterator it;
                        for (it = clients.begin(); it != clients.end();)
                            if (*it ==clients[i])
                                it = clients.erase(it);
                            else
                                it++;
                    }
                }
            }
        }
    }
    return 0;
}

 

Code côté client :

#include <SFML/Network.hpp>
#include "symEncPacket.h"
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
using namespace sf;
int main () {
     TcpSocket socketTCP;
    if (socketTCP.connect(IpAddress::LocalHost, 4567))
        cout<<"Ok"<<endl;
    SocketSelector selector;
    selector.add(socketTCP);
    string message;
    while (true) {
        SymEncPacket packet;
        packet.clear();
        message = "Ceci est un message TCP!";
        packet<<message;
        socketTCP.send(packet);
        if (selector.wait()) {
            if (selector.isReady(socketTCP)) {
                packet.clear();
                if (socketTCP.receive(packet) == Socket::Done) {
                    packet>>message;
                    //cout<<"Received from server (TCP) : "<<message<<endl;
                }
            }
        }
        //sleep(seconds(0.5f));
    }
    return 0;
}
 

Et une bête classe gérant l'envoi de paquet personnalisés côté serveur et côté client, ici j'envoie le message tel quel, pas de cryptage neccessaire pour reproduire le bug.

Voici le .cpp
#include "symEncPacket.h"

using namespace std;
using namespace sf;

const void* SymEncPacket::onSend (size_t& dataSize) {
    const char* datas = static_cast<const char*> (getData());
    buffer.assign(datas, datas + getDataSize());
    vector<char>::iterator it;
    string message;
    for (it = buffer.begin(); it != buffer.end(); it++)
         message += *it;
    cout<<"Message : "<<message<<endl;
    for (unsigned int i = 0; i < message.size(); i++)
        buffer.push_back(message.at(i));
    dataSize = buffer.size();
    return &buffer[0];
}
void SymEncPacket::onReceive (const void* data, size_t dataSize) {
    const char* datas = static_cast<const char*> (data);
    buffer.assign (datas, datas + dataSize);
    string message;
    vector<char>::iterator it;
    for (it = buffer.begin(); it != buffer.end(); it++)
         message += *it;
    for (unsigned int i = 0; i < message.size(); i++)
        buffer.push_back(message.at(i));
    append(&buffer[0], buffer.size());
}
#endif

 

Et voici le .h
#ifndef SYM_ENC_PACKET
#define SYM_ENC_PACKET
#include <SFML/Network.hpp>
#include "symEnc.h"
class SymEncPacket : public sf::Packet {
    private :
        virtual const void* onSend(std::size_t& dataSize);
        virtual void onReceive (const void* data, std::size_t dataSize);
        std::vector<char> buffer;
        std::vector<char> encBuffer;

};
#endif

 

« Modifié: Juin 24, 2013, 02:07:55 pm par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Bug, un caractère en trop dans mon paquet pour les packets perso.
« Réponse #3 le: Juin 24, 2013, 02:09:06 pm »
C'est avant envoi, ou après reception que tu as le bug ?

Et quand tu dis "un caractère en trop", c'est en trop par rapport à quoi ? Comment sais-tu combien d'octets le paquet est censé contenir ?
« Modifié: Juin 24, 2013, 02:10:59 pm par Laurent »
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Bug, un caractère en trop dans mon paquet pour les packets perso.
« Réponse #4 le: Juin 24, 2013, 02:09:57 pm »
Avant l'envoi, dans la fonction onSend, quand je fais le getData(), il y a un caractère en trop au début.

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Bug, un caractère en trop dans mon paquet pour les packets perso.
« Réponse #5 le: Juin 24, 2013, 02:17:22 pm »
Citer
Et quand tu dis "un caractère en trop", c'est en trop par rapport à quoi ? Comment sais-tu combien d'octets le paquet est censé contenir ?

Bah la fonction getDataSize() ne renvoie t'elle pas le nombre d'octets que contient le paquet ?

Et j'ai à chaque fois un octet en trop au début du paquet, je ne sais pas d'ou il vient peut être est-ce la taille du paquet qui est rajouté au début du paquet ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Bug, un caractère en trop dans mon paquet pour les packets perso.
« Réponse #6 le: Juin 24, 2013, 02:24:17 pm »
Citer
Avant l'envoi
Du coup on s'en fout un peu de tout le setup TCP, en terme de code minimal on a juste besoin de ta classe de paquet et du code qui met quelque chose dedans... Même tout ce que tu as dans la fonction onSend est inutile pour constater le bug, il suffit d'afficher getData() / getDataSize().

Citer
Bah la fonction getDataSize() ne renvoie t'elle pas le nombre d'octets que contient le paquet ?
Si. Mais c'est quoi ta référence pour dire "en trop" ? Tu compares ce que te donne getDataSize() à quoi ?

Citer
peut être est-ce la taille du paquet qui est rajouté au début du paquet ?
Non. Par contre il y a la taille de la chaîne, mais elle fait 4 octets, pas 1.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Bug, un caractère en trop dans mon paquet pour les packets perso.
« Réponse #7 le: Juin 24, 2013, 02:34:54 pm »
Citer
Si. Mais c'est quoi ta référence pour dire "en trop" ? Tu compares ce que te donne getDataSize() à quoi ?
Bah là j'essaye de comparer ce que donne getData() comparé à getDataSize().
Citer
Non. Par contre il y a la taille de la chaîne, mais elle fait 4 octets, pas 1.

Ha merci, c'était ça, il y avait en effet les 4 octets qui mentionnaient la taille de la chaine en trop, c'étais ça qu'il rajoutait à chaque fois avant que je renvoie mon message.

Je les ai ignorés avant de renvoiyer le message et là ça marche.
const void* SymEncPacket::onSend (size_t& dataSize) {
    const char* datas = static_cast<const char*> (getData());
    buffer.assign(datas, datas + getDataSize());
    vector<char>::iterator it = buffer.begin();
    string message="";
    it+=4;
    for (; it != buffer.end(); it++)
         message += *it;
    cout<<"Message : "<<message<<endl;
    for (unsigned int i = 0; i < message.size(); i++)
        buffer.push_back(message.at(i));
    dataSize = buffer.size();
    return &buffer[0];
}
 
PS : ça m'étonne je pensais que tu l'avais déja fait dans ton code source, le fait qu'il ne renvoie pas la taille de la chaine avec le getData(), vu que tu encapsules le code.
« Modifié: Juin 24, 2013, 02:38:31 pm par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Bug, un caractère en trop dans mon paquet pour les packets perso.
« Réponse #8 le: Juin 24, 2013, 02:53:57 pm »
Citer
Je les ai ignorés avant de renvoiyer le message et là ça marche.
Oui sauf que de l'autre côté ton paquet ne saura pas décoder la chaîne. C'est pas pour faire joli que j'ai mis la taille dans les données du paquet ;)

Citer
ça m'étonne je pensais que tu l'avais déja fait dans ton code source, le fait qu'il ne renvoie pas la taille de la chaine avec le getData(), vu que tu encapsules le code.
Il faut envoyer la taille de la chaîne ! Sinon comment je sais où elle s'arrête, pour la relire ?

Ce que tu fais dans onSend/onReceive ne doit pas altérer les données, sf::Packet a son propre protocole de communication, si tu touches aux données ton paquet ne va plus rien comprendre après réception.

En clair, ce qui sort de onReceive doit être strictement ce qui était entré dans le onSend correspondant.

PS : je comprends vraiment pas ce que tu fais dans onSend. Au final tu te retrouves avec la même chose en double dans 'buffer', non ?
« Modifié: Juin 24, 2013, 02:56:36 pm par Laurent »
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Bug, un caractère en trop dans mon paquet pour les packets perso.
« Réponse #9 le: Juin 24, 2013, 03:09:59 pm »
Citer
Il faut envoyer la taille de la chaîne ! Sinon comment je sais où elle s'arrête, pour la relire ?

Ce que tu fais dans onSend/onReceive ne doit pas altérer les données, sf::Packet a son propre protocole de communication, si tu touches aux données ton paquet ne va plus rien comprendre après réception.

Ok, en effet c'est vrai quand je touche aux données dans onSend, le onReceive correspondant ne comprend plus rien.

Le problème c'est que je veut récupérer les données et les crypter avant de les envoyer, et ainsi les décrypter à la réception, malheureusement, il me crypte aussi la taille du paquet, du coup, dans ma plus grosse appli parfois ça bug, je reçois un paquet avec rien dedans.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Bug, un caractère en trop dans mon paquet pour les packets perso.
« Réponse #10 le: Juin 24, 2013, 03:15:16 pm »
Et ça gêne en quoi qu'il y ait la taille de la chaîne dedans ? A ce niveau ce que tu traites c'est un paquet d'octets quelconques, donc peu importe ce qu'il y a dedans (et dans la fonction onSend, c'est pas vraiment tes affaires) ce que tu fais devrait toujours marcher pareil. Tu ne peux rien supposer sur le contenu que tu reçois, et encore moins essayer de l'interpréter en chaîne de caractères.
Laurent Gomila - SFML developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Bug, un caractère en trop dans mon paquet pour les packets perso.
« Réponse #11 le: Juin 24, 2013, 03:16:20 pm »
Au fait le terme correct est "chiffrer", pas "crypter" ;)
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Bug, un caractère en trop dans mon paquet pour les packets perso.
« Réponse #12 le: Juin 24, 2013, 03:24:35 pm »
Ha ok donc je devrai selon toi, directement chiffrer sur les octets et pas réinterprêter ça en chaine de caractère, avant d'envoyer, c'est bien ça ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Bug, un caractère en trop dans mon paquet pour les packets perso.
« Réponse #13 le: Juin 24, 2013, 03:34:25 pm »
C'est tout à fait ça.

onSend est juste censée transformer une soupe d'octets en une autre soupe d'octets ; ensuite onReceive doit retransformer cette dernière soupe d'octets en la soupe d'octets originale.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Bug, un caractère en trop dans mon paquet pour les packets perso.
« Réponse #14 le: Juin 24, 2013, 03:57:06 pm »
Ha ok j'ai compris alors pourquoi ça plante mon système.