Erreur de tansmission (octet manquant)

Signaler
Messages postés
5
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
26 juillet 2007
-
Messages postés
5
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
26 juillet 2007
-
Bonjour, je suis en train de développer un client serveur sous C++ et je rencontre des difficultes lors de la mise en oeuvre du serveur, je m'explique :
J'ai développé un client et un serveur, je les ai lancé en local (sur une même machaine, avec @IP pour le client = 127.0.0.1), aucun problème !
Par contre maintenant je viens de mettre l'application serveur sur une autre machine @IP=192.168.0.1, j'ai modifié @IP qu'il fallait dans le client, mais maintenant j'ai des erreurs dans la transmission serveur->client. (Il faut savoir que j'envoie au total plus 100 000 octets)

voici le code de l'envoi serveur :

    void sendPacket(char* toSend, int len) {
        int data_env=0;
        int trans_data=0;
        while (data_env<len) {
            trans_data=send(socket,toSend+data_env,T_SEND_DATA,0);
            data_env+=trans_data;
        }
        printf("donnéees envoyées : %i\n",data_env);
    }


voici le code de reception client :

char* Client::recvPacket() {
    char* recept = (char*) malloc (T_BUFF);
    int res;
    int total=0;
    int i=0;
    bool sortir=false;
    while (!sortir && ((res=recv(fdSock,instruction,T_BUFF,0))<=T_BUFF) && (res>0)) {
        printf("recep!!!!\n");
         if (i>0) {
            char* temp = (char*) malloc (i+T_BUFF);
            strcpy(temp,recept);
            recept=temp;
        }
        total+=res;
        strcpy(recept+i,instruction);
        i=i+T_BUFF;
        if (strstr(instruction,"%")!=NULL) {
            printf("ON SORT !!\n");
            sortir=true;
        }
    }
    if (res<-1)  perror("Erreur réception instruction\n");
    //printf("commande : %s\n",recept);
    return recept;
}

Et si vous pouviez me donner quelques conseils aussi ;
        if (strstr(instruction,"%")!=NULL) {

            printf("ON SORT !!\n");

            sortir=true;

        }

Je trouve cela vraiment pas top ! (toSend contient '%', je le rajoute à chaque fois que je veux envoyez un char*)

Merci d'avance !

5 réponses

Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
Salut,

Ben déja dans le client tu utilises strcpy et strstr, ces fonctions
sont faites pour travailler sur des chaines, tu ne peux pas les
utiliser directement sur ce qui t'es retourné par recv().. et puis au
lieu d'afficher des messages comme "on sort" ou "recept", affiche
plutot les valeurs des variables de ta fonctions, le but c'est de
comprendre ce qu'il se passe dans ta fonction, et pour ca il faut un
maximum d'info utiles.
Messages postés
5
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
26 juillet 2007

Je crois que tu as dû mal voir, le résultat est retourné dans res (resultat), ensuite je sauvegarde recept (et non pas res) dans une nouvelle zone mémoire plus grande et je concatène avec ce que je viens de recevoir.
J'envoie des paquets de 256 caractères, je précise que j'envoie une chaine de 100 000 caractères, je la découpe donc en petits morceaux de 256. Le résultat je l'ai :
par exemple :
en émission : (500 octects ok)aaaabbbbcccc(600 octets ok)(le reste)....
en réception : (500 octects ok)aaaacccc(600 octets ok)(le reste)....

Ce que je na sais pas c'est si les "b" arrivent plus tard dans la chaine.

Genre :
Serveur emission aaaabbbbcccc
                                                                               cccc~~~~aaaa reception Client ("renvoie ~~~~ j'ai mal recu" et donc les bbbb arriveraient après (les cccc) dans la chaine.
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
Salut,

Au moment ou tu fais strcpy(recept+i,instruction), qu'est ce qui te
permet d'affirmer que instruction pointe bien sur une chaine valide,
terminée par '\0' ?
Messages postés
285
Date d'inscription
mardi 28 décembre 2004
Statut
Membre
Dernière intervention
20 janvier 2013

Salut !
Déjà ya un gros problème d'allocation...

char* recept = (char*) malloc (T_BUFF);
...
char* temp = (char*) malloc (i+T_BUFF);

Ils sont où les free() ???????

Ensuite :

char* recept = (char*) malloc (T_BUFF); //Tu alloue, OK, mais tu n'a aucune idée de ce que contient ta chaine. Rien n'indique qu'il y a des 0 dedans. Bref : fuite de mémoire assurée

if (i>0)
{
char* temp = (char*) malloc (i+T_BUFF);
strcpy(temp,recept); //Tu copie une chaine que tu ne connai pas et dont tu n'es pas sur de la fin : fuite de mémoire + buffer overflow
//D'ailleur ca ne sert a rien cette copie puisque tu fait un strcpy de recept dans temp, donc tmp recept, puis tu fait recept <- temp. Pour une concacténation de chaine c'est strcat qu'il faut utiliser. strcpy ne fonctionnera comme tu le veux QUE si temp ""
recept=temp; //Premier passage dans la boucle : i=0 : recept toujours égale à n'importe quoi.
}

strcpy(recept+i,instruction); // Meme remarque, strcat et non strcpy !!!

while (!sortir && ((res=recv(fdSock,instruction,T_BUFF,0))<=T_BUFF) && (res>0)) {
!sortir : Ok
res = recv(...) : A faire dans la boucle de préférence.
res > 0 : Idem, d'autant plus que res = 0 n'est pas une erreure mais une fin de connection

Il doit rester pas mal d'erreur mais j'ai pas le temps de m'y attarder plus que ca.
Un peu plus de rigueure ne te feraient pas de mal. Au passage, tu es en C++ alors malloc/free c'est pas ce qu'il y a de mieux. Préfères new et delete.
Espace un peu mieux ton code aussi tu t'y retrouvera mieu (enfin ca c'est vraiment secondaire).

Quand à tes indices, j'ai pas prit le temps de vérifier mais n'oublie pas qu'un indice est un offset mais n'est pas une taille. Donc bien faire attention car faire des choses comme "strcpy(recept+i,instruction);", il ne faut pas oublier que (recept + i) n'est pas le premier caractère null, mais le dernier non null.
Messages postés
5
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
26 juillet 2007

Bonjour, merci de m'avoir répondu, et merci pour la leçon, O seigneur dieu qui détient la science infuse du développement C++. (Des fois on se demande sur quelle planète on vit...)

Pour ceux que ca interesse, j'ai refait mes fonction d'emission et de réception :

//////******Recep********//////
char* Client::recvPacket() {
    char* recept = (char*) malloc (1000000);
    int res;
    int total=0;
    while ((res=recv(fdSock,instruction,T_BUFF,0))>0) {
        cpNByte(recept+total,instruction,res);
        total+=res;
    }
    if (res<-1)  perror("Erreur réception instruction\n");
    recept[total]='\0';
    return recept;
}

void Client::cpNByte(char* dest, char* source, int cpt) {

    for (int i=0;i<cpt;i++) {
        *(dest+i)=*(source+i);
    }
}

/////////*********Emiss********///////
    void sendPacket(char* toSend, int len) {
        int data_env=0;
        int trans_data=0;
        while (data_env<len) {
            trans_data=send(socket,toSend+data_env,T_SEND_DATA,0);
            if (trans_data<0) perror ("erreur send\n");
            if (trans_data!=T_SEND_DATA) {
                printf("pas meme envoie : envoyé = %i\n",trans_data);
                exit(-1);
            }
            data_env+=trans_data;
        }
        printf("donnéees envoyées : %i\n",data_env);
    }

Il reste le malloc de la fonction Recept qui n'est vraiment pas beau, je modifierai prochainement.
Bonne continuation à tous !