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 :

Problème lors de l'envoi d'une matrice par socket


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti Avatar de Blackbelt_29
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 19
    Par défaut Problème lors de l'envoi d'une matrice par socket
    Bonjour,

    J'essaye d'envoyer une matrice de float (tableau à deux dimensions) par socket, avec les cours sur internet j'arrive bien à envoyer d'un client vers un serveur une chaine de caractère ainsi que des structures. Du coup mon idée était justement d'utiliser des structures afin d'envoyer mon tableau à deux dimensions. Du coup je crée un tableau 2*2 que je copie dans ma structure et je l'envoie. Le problème est que quand j'essaye de la récupérer j'ai une erreur de segmentation, et je ne vois absolument pas d'où ça peut venir ?


    Voici le code en question du côté serveur:

    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
    //Création de la structure
        typedef struct Image Image;
    struct Image{
        float** tabImage;
    };
     
        float **tab2=NULL;
    tab2=allocation(2,2);
    tab2[0][0]=2.0;
    tab2[0][1]=4.32;
        tab2[1][0]=1.47;
        tab2[1][1]=8.37;
     
    Image NewImage;
    NewImage.tabImage=allocation(2,2);//Fonction qui alloue dynamiquement la matrice
    int i,j;
     
         //Recopie les valeurs de tab2 dans la structure
     
         for(i=0;i<2;i++)
        for(j=0;j<2;j++)
            NewImage.tabImage[i][j]=tab2[i][j];
     
         //Envoie la structure
     sock_err = send(csock,&NewImage,sizeof(NewImage), 0);


    Et voici le code en question côté client
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /*Déclaration de la structure coté client
    typedef struct Image Image;
        struct Image{
            float** tabImage;
        };
     
        Image NewImage;
        NewImage.tabImage=allocation(2,2); //allocation  dynamique du tableau
        recv(sock,&NewImage.tabImage ,sizeof(NewImage), 0);
    //Reception de la structure
    Je n'ai pas mis le reste de la fonction car je pense que l'erreur vient de ces lignes (car ça marche bien sinon avec une chaine de caractère ou une structure avec des int, double...),mais si il faut je la mettrai sans problème !

    Merci !

  2. #2
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Il y a deux incompréhensions ici :

    • lorsque tu passes ta structure à send, ce ne sont pas les données de la matrice qui sont transmises mais le contenu du pointeur vers le bloc mémoire où se trouve cette matrice. Ce bloc est alloué séparément, il ne fait pas partie de ta structure qui en a simplement connaissance.
    • sizeof est un opérateur statique, tu ne peux pas l'utiliser pour récupérer la taille d'un bloc mémoire déterminée à l'exécution. sizeof(<variable de type struct Image>) retournera toujours la même valeur n'importe où dans le programme (à savoir ici sizeof(float **)), que la matrice pointée fasse 2x2 ou 16045x1454013.

  3. #3
    Membre averti Avatar de Blackbelt_29
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 19
    Par défaut
    Merci pour ta réponse


  4. #4
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    • Que crois-tu qu'il se passe en mémoire lorsque tu crées ta structure et que tu alloues dynamiquement de la place pour ses membres ?
    • Ce que send attend, c'est une adresse mémoire et le nombre d'octets à lire à partir de cette adresse. Que crois-tu qu'il se passe lorsque tu lui donnes l'adresse d'une variable de type struct Image et la taille d'une struct Image ?

    Ce sont de vraies questions, je voudrais savoir ce que tu as déjà assimilé du fonctionnement.


    Citation Envoyé par Blackbelt_29 Voir le message
    Ça c'est correct mais plus généralement, la taille du bloc alloué a été calculée par ta fonction allocation, c'est l'argument de malloc.

    Citation Envoyé par Blackbelt_29 Voir le message
    , ou bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    4*sizeof(NewImage.TabImage)
    Ça c'est incorrect. Quelle est la différence entre sizeof(NewImage.TabImage) et sizeof(float) selon toi ?

  5. #5
    Membre averti Avatar de Blackbelt_29
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 19
    Par défaut
    Merci pour ta réponse ! J'ai regardé de nouveau le cours et voila ce que j'ai compris :

    Que crois-tu qu'il se passe en mémoire lorsque tu crées ta structure et que tu alloues dynamiquement de la place pour ses membres ?
    À ce moment-là le programme va réserver des places dans la mémoire (un nombre d'adresses égal à la dimension de ma matrice) du coup je vais réserver dans la mémoire de l'ordinateur 4 adresses de celle-ci, qui pour l'instant ne contiennent aucune valeur !

    Ce que send attend, c'est une adresse mémoire et le nombre d'octets à lire à partir de cette adresse. Que crois-tu qu'il se passe lorsque tu lui donnes l'adresse d'une variable de type struct Image et la taille d'une struct Image ?
    Justement c'est peu être là où je n'ai pas trop compris , pour moi lorsque je fais &NewImage TabImage je ne donne pas à send l'adresse de la variable, mais la valeur contenue à l'adresse de cette adresse. Du coup j'envoie les valeurs contenues dans les adresses que je venais d'allouer dynamiquement .

    En gros quand je fais &NewImage TabImage pour moi il va chercher la valeur à cette adresse et l'envoyer (ici il enverra 32) :
    Adresse Valeur
    0xFFFFFF 32


    Ça c'est incorrect. Quelle est la différence entre sizeof(NewImage.TabImage) et sizeof(float) selon toi ?
    Pour moi sizeof(float) correspond à la taille prise en mémoire d'un flottant et sizeof(NewImage.TabImage) correspond lui à la taille d'un tableau non alloué donc pas grand chose

    Edit : Du coup si je corrige le code par cette ligne est-ce correct ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sock_err = send(csock,*NewImage.tabImage,4*sizeof(float), 0);

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par défaut
    Ce ne sera pas suffisant, parce que NewImage.TabImage est un tableau de pointeurs.
    Si cette matrice a été allouée intelligemment, alors un send(csock, &(NewImage.tabImage[0][0]), 2*2*sizeof(float), 0) pourrait suffire. Mais dans le cas d'un tableau de tableaux (ce qui est hélas le cas le plus fréquent chez ceux qui débutent en C), même ça ne suffira pas, et tu devras faire une boucle de send() qui envoie séparément chaque ligne de ta matrice.
    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
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    551
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 551
    Par défaut
    Bonjour
    Citation Envoyé par Blackbelt_29 Voir le message
    Bonjour,

    J'essaye d'envoyer une matrice de float (tableau à deux dimensions) par socket, avec les cours sur internet j'arrive bien à envoyer d'un client vers un serveur une chaine de caractère ainsi que des structures. Du coup mon idée était justement d'utiliser des structures afin d'envoyer mon tableau à deux dimensions. Du coup je crée un tableau 2*2 que je copie dans ma structure et je l'envoie. Le problème est que quand j'essaye de la récupérer j'ai une erreur de segmentation, et je ne vois absolument pas d'où ça peut venir ?


    Voici le code en question du côté serveur:

    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
    //Création de la structure
        typedef struct Image Image;
    struct Image{
        float** tabImage;
    };
     
        float **tab2=NULL;
    tab2=allocation(2,2);
    tab2[0][0]=2.0;
    tab2[0][1]=4.32;
        tab2[1][0]=1.47;
        tab2[1][1]=8.37;
     
    Image NewImage;
    NewImage.tabImage=allocation(2,2);//Fonction qui alloue dynamiquement la matrice
    int i,j;
     
         //Recopie les valeurs de tab2 dans la structure
     
         for(i=0;i<2;i++)
        for(j=0;j<2;j++)
            NewImage.tabImage[i][j]=tab2[i][j];
     
         //Envoie la structure
     sock_err = send(csock,&NewImage,sizeof(NewImage), 0);


    Et voici le code en question côté client
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /*Déclaration de la structure coté client
    typedef struct Image Image;
        struct Image{
            float** tabImage;
        };
     
        Image NewImage;
        NewImage.tabImage=allocation(2,2); //allocation  dynamique du tableau
        recv(sock,&NewImage.tabImage ,sizeof(NewImage), 0);
    //Reception de la structure
    Je n'ai pas mis le reste de la fonction car je pense que l'erreur vient de ces lignes (car ça marche bien sinon avec une chaine de caractère ou une structure avec des int, double...),mais si il faut je la mettrai sans problème !

    Merci !

    « Send » peut envoyer une structure à condition que la structure ne contienne que les types de bases (c’est à dire des champs sans pointeur ou pointeur sur bidule) et dans ce cas, l’envoi de la structure peut se faire aisément en passant à « send() » l'adresse de votre structure en question et sa taille.
    Dans le cas où les champs de votre structure sont composés de pointeurs, il faut envoyer les données pointées par le pointeur en question. Parce que si vous envoyez le pointeur, vous ne faites qu’envoyer la valeur du pointeur : en clair là ou pointe votre pointeur donc son adresse.
    Mais attention, si vos tests avec envoi de structure dont les champs contiennent des pointeurs fonctionnent, c’est parce que serveur et client sont sur la même machine. Dans le cas où le serveur est sur une autre machine que celle du client, cela ne marchera pas pour les raisons que j’ai énoncé précédemment.

    Cependant, je me permets toute de même de vous poser la question suivante : pourquoi souhaitez-vous envoyer systématiquement une structure avec un champ qui est un pointeur sur quelque chose ?
    à bientôt

Discussions similaires

  1. Problème lors de l'envoi d'une newsletter
    Par ghir_ana dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 06/07/2011, 23h51
  2. [AJAX] Envoie d'une requête AJAX
    Par tidus_6_9_2 dans le forum AJAX
    Réponses: 16
    Dernier message: 14/04/2010, 15h23
  3. Envoi d'une matrice sur socket UDP
    Par caubios dans le forum Qt
    Réponses: 0
    Dernier message: 10/02/2010, 19h10
  4. Réponses: 4
    Dernier message: 04/02/2010, 14h44
  5. Réponses: 9
    Dernier message: 15/03/2007, 16h17

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